딥러닝을 사용한 로또 번호 예측 실험


딥러닝을 공부하며, 이것을 사용하여 무엇을 해볼까 생각해보다 로또 번호 예측을 해보기로 했다.
최근에 딥러닝 공부를 위해 구입한 O’REILLY에서 나온 ‘Deep Learning Cookbook’에 나온 예제 중 셰익스피어가 쓴 것 같은 문장 생성하기를 참조하기로 했다파이선은 딥러닝 공부하며 처음 접해본 언어라 책의 예제 소스를 많이 참조했다참조한 예제는 RNN(Recurrent Neural Network)을 사용하고 있다. RNN은 일정한 순서를 가진 입력의 경우 흔히 사용한다고 한다.

1. 당첨 번호들을 사용하여 데이터 셋을 만든다.

트레이닝 세트와 테스트 세트로 나눠 테스트를 하는 것이 좋지만 일단은 테스트 세트 없이 학습 loss accuracy만을 보기로 했다로또 당첨 번호들을 로또 사이트에서 다운받은 다음 text형태로 만든 뒤, 이를 읽어 리스트 형태의 데이터로 만든다.

2. RNN 모델을 만든다.

RNN 모델은 Keras(https://keras.io/) API를 사용하여 만들었다.

입력과 출력은 45개의 one-hot 코딩된 데이터(로또 번호가 1~45이므로) 형태를 사용한다.
입력 받은 데이터는 Keras에서 제공하는 LSTM(Long Short-Term Memory Layer)를 사용하고, 과적합 방지를 위해 GaussianDropout레이어도 중간에 넣어준다LSTM은 총 6개의 Layer를 쌓고 node 개수는 256개를 사용했다LSTM Layer 다음에는 일반적인 Neural Network을 두어 45개의 one-hot 코딩된 값을 출력하게 했다. Activationsoftmax를 사용했다.

3. 모델 Training


위는 Training 코드와 같다. 먼저 모델을 만들고 fit_generator를 사용하여 학습시킨다. 데이터는 data_generator를 만들어 학습할 때 데이터를 넘겨준다EarlyStopping Callback을 두어 학습이 진행되지 않으면(loss 값이 더 이상 감소하지 않으면), 학습을 멈추게 하였다.
테스트 셋 유무에 따라 다른 EarlyStopping Callback이 다른 loss/val_loss 값을 체크하게 하였다학습이 끝나면 모델의 weight값은 save_weights api를 사용하여 파일로 저장하여 필요시 다시 사용하게 하였다.
아래 그림은 data_generator에서 만들어지는 입력 데이터가 어떤 형태인지 보기 쉽게 도식화한 것이다.


위 함수를 사용해 동일한 형태(layer의 개수나 node 개수가 동일)의 모델에 다른 chunk size들을 사용해 학습했을 때 학습 성과에 차이가 있는지 테스트해보았다아래 그림을 보면 입력 데이터의 chunk size가 달라질 때 마다 학습 acc(accuracy)가 달라지는 것을 볼 수 있다.
가장 높은 acc값이 0.5366이다. 이 정도로 과연 학습이 이루어 졌는지 의구심이 든다.
모델에 문제가 있는지 혹은 다른 파라메터들을 더 수정해가며 학습 정확도를 올리는 테스트가 필요해 보인다. 학습 정확도를 더 올리고 난 다음, 테스트 세트를 사용하여 테스트를 병행하며 학습을 진행해야 할 것 같다.

그리고, 같은 chunk size일때도 아래 표와 같이 학습 accuracy가 다르게 나오는 경우도 종종 있다Chink size 26으로 동일하지만 학습 마다 accuracy에 차이가 발생하는 경우가 있다.

trainning( 2 / 5 ) ...  zoo/c26
Epoch 1/50
 - 56s - loss: 3.8453 - acc: 0.0260
Epoch 2/50
 - 49s - loss: 3.7964 - acc: 0.0311
Epoch 3/50
 - 49s - loss: 3.7040 - acc: 0.0434
Epoch 4/50
 - 50s - loss: 3.4581 - acc: 0.0696
Epoch 5/50
 - 49s - loss: 3.3783 - acc: 0.0782
Epoch 6/50
 - 49s - loss: 3.3307 - acc: 0.0852
Epoch 7/50
 - 49s - loss: 3.2740 - acc: 0.0913
Epoch 8/50
 - 50s - loss: 3.2188 - acc: 0.0983
Epoch 9/50
 - 50s - loss: 3.1780 - acc: 0.1053
Epoch 10/50
 - 49s - loss: 3.2392 - acc: 0.1068
Epoch 11/50
 - 50s - loss: 3.0555 - acc: 0.1258
Epoch 12/50
 - 49s - loss: 3.0689 - acc: 0.1311
Epoch 13/50
 - 50s - loss: 2.9912 - acc: 0.1446
Epoch 14/50
 - 50s - loss: 2.9903 - acc: 0.1533
Epoch 15/50
 - 49s - loss: 2.9901 - acc: 0.1602
Epoch 16/50
 - 50s - loss: 2.9815 - acc: 0.1686
Epoch 17/50
 - 49s - loss: 2.9671 - acc: 0.1769
Epoch 18/50
 - 51s - loss: 2.8854 - acc: 0.1928
Epoch 19/50
 - 49s - loss: 2.9818 - acc: 0.1882
Epoch 20/50
 - 49s - loss: 2.9939 - acc: 0.1962
trainning( 2 / 5 ) ...  zoo/c26
Epoch 1/50
 - 55s - loss: 3.8471 - acc: 0.0261
Epoch 2/50
 - 49s - loss: 3.7991 - acc: 0.0303
Epoch 3/50
 - 49s - loss: 3.7772 - acc: 0.0354
Epoch 4/50
 - 50s - loss: 3.8049 - acc: 0.0290
Epoch 5/50
 - 49s - loss: 3.7866 - acc: 0.0333

4. Prediction

학습 정확도는 낮지만, 그래도 로또 번호 예측을 해보기로 했다. 각각의 학습 정확도가 기대할 만한 수준이 되지 않아, 그중 가장 높은 3개의 학습결과 weights값들을 사용해 각각의 파라메터 모델들이 출력하는 결과의 평균을 예측 값으로 사용하기로 했다. Chunk size22,23,24인 학습 파라메터를 사용했다.
Prediction 함수는 아래와 같다. 모델을 만든 후 load_weights api를 사용하여 학습된 weights를 모델에 로드하여 predict api를 사용하여 결과를 예측한다. 이 예측된 결과는 softmax 활성화 함수의 결과 이므로 일종의 확률 분포로 볼 수 있다.


6개의 숫자 O1~ O6를 예측하는 전체 예측 과정은 다음과 같다.
a. 입력 데이터 Ichunk size별로 predict 함수를 호출하여 예측 확률을 구한다.
b. a의 결과들을 합한 확률을 가지고 np.ramdom.multinomial함수를 사용하여 시뮬레이션 한 결과를 최종 On번째 예측 확률로 사용한다.
c. 입력 데이터 I에 위 b의 예측 결과 중 가장 높은 3개의 숫자를 하나씩 넣으며 위 과정을 반복하여 On+1번째 예측 확률을 찾는다.
d. O6까지의 예측 값을 찾을 때까지 위의 과정을 반복한다. 반복되는 n번째 예측 결과는 평균을 내어 사용한다.

위 예측 과정을 마친 후 O1~O6의 확률 분포는 아래 그림과 같다. 기대되는 확률이 너무 낮게 나왔다.


5. conclusion

로또 번호 자체가 학습을 통한 예측이 불가능할 수도 있다.
실험 결과, 학습이 잘 이루어지지 않은 것처럼 보인다. 학습 정확도도 낮고 결과의 확률 분포는 학습 정확도 보다 더 많이 떨어진다시간이 날 때 RNN이외의 모델이나, 학습데이터 변형 등을 통해 학습 정확도를 높이는 테스트를 진행해야 할 것 같다.


댓글

  1. 로또 번호는 학습의 대상이 아니죠,,,하하하

    답글삭제
  2. 매번 시행하는게 독립이라서 아무 의미없습니다.

    답글삭제

댓글 쓰기

이 블로그의 인기 게시물

windows에서 간단하게 크롬캐스트(Chromecast)를 통해 윈도우 화면 미러링 방법

쉽게 설명한 파티클 필터(particle filter) 동작 원리와 예제

간단한 cfar 알고리즘에 대해

아두이노(arduino) 심박센서 (heart rate sensor) 심박수 측정 example code