본문 바로가기
Python

파이썬 딥러닝을 이용하여 로또 번호 예측하기 - 2부

by 아짱이아빠 2022. 4. 30. 18:15
반응형

지난 1부에서는 파이썬 딥러닝 중 하나인 LSTM을 통해 로또 번호 중 1개 자리에 대해서 예측해 보는 프로그램을 만들어 보았다.

2부에서는 로또 사이트에서 지난 1회 차부터 최근 회차까지의 1등 당첨 번호를 다운로드하여 이를 바탕으로 훈련된 모델로 다음 회차의 1등 당첨 번호 6개를 예측하는 방법에 대해 알아보겠다.

사실 과거의 1등 당첨 번호를 다운로드하는 것은 예전 포스트에서 알아봤었고 번호를 예측하는 것은 지난 1부에서 알아본 내용을 for 문을 사용하여 6번 반복하는 것이다.

 

또한, 항상 얘기하듯이 이번 차수의 로또 1등 당첨 번호 6개는 이전 회차의 당첨 번호와 아무런 상관관계가 없는 완전히 독립된 시스템이기 때문에 이전 데이터로 모델을 훈련시키는 것 자체가 의미가 없다.

그냥 파이썬을 통해 딥러닝을 쉽게 활용할 수 있다는 정도로 생각하고 가볍게 봐주면 좋을 것 같다.

 

[로또 사이트에서 지난 회차 정보 다운로드]

import pandas as pd
import requests
from tqdm import tqdm
import json
import math
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense, LSTM

위의 코드는 프로그램에 사용되는 라이브러리를 임포트 한다.

‘tqdm’과 ‘json’은 로또 사이트에서 정보를 다운로드 시에 필요하며 나머지는 데이터 계산과 LSTM을 위해 필요한 라이브러리이다.

 

다음의 코드는 로또 사이트에서 1회부터 최근 차수까지의 1등 당첨 번호와 기타 정보를 다운로드하여 저장하는 코드이다.

def getLottoWinInfo(minDrwNo, maxDrwNo):

  drwtNo1 = []
  drwtNo2 = []
  drwtNo3 = []
  drwtNo4 = []
  drwtNo5 = []
  drwtNo6 = []
  bnusNo = []
  totSellamnt = []
  drwNoDate = []
  firstAccumamnt = []
  firstPrzwnerCo = []
  firstWinamnt = []

  for i in tqdm(range(minDrwNo, maxDrwNo+1, 1)):
    req_url = "http://www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo=" + str(i)
    req_lotto = requests.get(req_url)
    lottoNo = req_lotto.json()
    drwtNo1.append(lottoNo['drwtNo1'])
    drwtNo2.append(lottoNo['drwtNo2'])
    drwtNo3.append(lottoNo['drwtNo3'])
    drwtNo4.append(lottoNo['drwtNo4'])
    drwtNo5.append(lottoNo['drwtNo5'])
    drwtNo6.append(lottoNo['drwtNo6'])
    bnusNo.append(lottoNo['bnusNo'])
    totSellamnt.append(lottoNo['totSellamnt'])
    drwNoDate.append(lottoNo['drwNoDate'])
    firstAccumamnt.append(lottoNo['firstAccumamnt'])
    firstPrzwnerCo.append(lottoNo['firstPrzwnerCo'])
    firstWinamnt.append(lottoNo['firstWinamnt'])

    lotto_dict = {"추첨일":drwNoDate, "Num1":drwtNo1, "Num2":drwtNo2, "Num3":drwtNo3, "Num4":drwtNo4, "Num5":drwtNo5,
                  "Num6":drwtNo6, "bnsNum":bnusNo, "총판매금액":totSellamnt, "총1등당첨금":firstAccumamnt,
                  "1등당첨인원":firstPrzwnerCo,"1등수령액":firstWinamnt}

  df_lotto = pd.DataFrame(lotto_dict)
  return df_lotto

lotto_df = getLottoWinInfo(1,1012)

코드는 크게 다운로드할 정보를 저장할 빈 공간을 만들고 for 문을 통해 로또 사이트에 접속하여 각 정보를 요청하여 받은 정보를 해당 공간에 저장하는 기능을 정의한 부분과 이를 실행시켜 ‘lotto_df’에 저장하는 기능으로 구성된다. 

여기서는 1회차부터 1012회 차까지 실행시켜 1등 당첨 번호와 당첨금 등 기타 정보를 다운로드한다.

 

이렇게 저장된 정보를 열어보면 아래와 같다.

1회차부터 1012회차 까지의 로또 1등 번호 결과
(1회차부터 1012회차 까지의 로또 1등 번호 결과)

 

[다음 회차의 로또 당첨 번호 6자리 예측]

앞에서 얘기했듯이 여기서 부터는 지난 1부에서 알아본 내용을 6개 자리로 늘려서 6번 반복한다.

그러므로 아래의 링크로 1부의 내용을 먼저 확인하는 것이 도움이 될 것이다.

 

파이썬 딥러닝을 이용하여 로또 번호 예측하기 - 1부

이번에는 2부에 걸쳐 딥러닝 중 하나인 LSTM을 이용하여 로또 번호를 예측해보는 파이썬 코드에 대해 알아보겠다. 이전의 포스트에서 과거 1등 로또 번호들의 합을 바탕으로 기계학습을 하여 다

superhky.tistory.com

 

우선 아래의 코드처럼 다운로드하여 저장한 데이터에서 각 6개 자리의 수를 각각의 변수 ‘data_x’에 저장한다.

그리고 데이터만 ‘.values’ 함수를 사용하여 빼내 ‘dataset_x’ 변수에 저장한다.

마지막은 훈련에 사용할 데이터 크기를 정하며 1부에서와 동일하게 80%의 데이터를 훈련에 사용한다.

data_1 = lotto_df.filter(['Num1'])
data_2 = lotto_df.filter(['Num2'])
data_3 = lotto_df.filter(['Num3'])
data_4 = lotto_df.filter(['Num4'])
data_5 = lotto_df.filter(['Num5'])
data_6 = lotto_df.filter(['Num6'])

dataset_1 = data_1.values
dataset_2 = data_2.values
dataset_3 = data_3.values
dataset_4 = data_4.values
dataset_5 = data_5.values
dataset_6 = data_6.values

training_data_len = math.ceil(len(dataset_1)*.8)

 

반응형

 

다음은 각 데이터를 0에서 1사이로 정규화하는 부분이다.

정규화한 데이터는 ‘scaled_data_x’에 각 저장한다.

scaler = MinMaxScaler(feature_range=(0,1))

scaled_data_1 = scaler.fit_transform(dataset_1)
scaled_data_2 = scaler.fit_transform(dataset_2)
scaled_data_3 = scaler.fit_transform(dataset_3)
scaled_data_4 = scaler.fit_transform(dataset_4)
scaled_data_5 = scaler.fit_transform(dataset_5)
scaled_data_6 = scaler.fit_transform(dataset_6)

 

다음은 이 다음에 수행할 for 문에서 각 자리의 번호를 하나씩 호출하기 위해 데이터 프레임 형식으로 데이터들을 만드는 것이다.

참고로 이 부분은 파이썬을 잘 사용하지 못하기 때문에 좀 무식한 방법을 사용한 것일 수 있거나 아니면 불필요한 부분일 수 있다.  

new_df = pd.DataFrame()

new_df['Num1'] = pd.DataFrame(scaled_data_1)
new_df['Num2'] = pd.DataFrame(scaled_data_2)
new_df['Num3'] = pd.DataFrame(scaled_data_3)
new_df['Num4'] = pd.DataFrame(scaled_data_4)
new_df['Num5'] = pd.DataFrame(scaled_data_5)
new_df['Num6'] = pd.DataFrame(scaled_data_6)

 

마지막 코드 부분은 아래와 같다.

number= ['Num1', 'Num2', 'Num3', 'Num4', 'Num5', 'Num6']
result=[]

for item in number:
  train_data=[]
  train_data = new_df[item].values
  train_data = train_data[0:training_data_len]
  x_train=[]
  y_train=[]
  
  for i in range(60, len(train_data)):
    x_train.append(train_data[i-60:i])
    y_train.append(train_data[i])
    
  x_train, y_train = np.array(x_train), np.array(y_train)
  x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))
  
  model = Sequential()
  model.add(LSTM(50, return_sequences=True, input_shape = (x_train.shape[1], 1)))
  model.add(LSTM(50, return_sequences = False))
  model.add(Dense(25))
  model.add(Dense(1))
  model.compile(optimizer='adam', loss = 'mean_squared_error')
  model.fit(x_train, y_train, batch_size=1, epochs=10)
  
  ins_df = lotto_df.filter([item])
  print(item)
  last_60_data = ins_df[-60:].values
  last_60_data_scaled = scaler.transform(last_60_data)

  x_test=[]
  x_test.append(last_60_data_scaled)
  x_test = np.array(x_test)
  x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1],1))
  
  pred_data=[]
  pred_data = model.predict(x_test)
  pred_data = (scaler.inverse_transform(pred_data))
  result.append((np.around(pred_data)))

print(result)

 

좀 복잡해 보이지만 그렇지 않다.

for 문에서 제일 먼저 ‘Num1’에 저장된 1회 차부터 최근 회차(1012회 차)까지의 1등 당첨 번호 중 첫째 자리의 수들을 통해 다음 회차 로또 1등 당첨 번호의 첫째 자리를 예측한다.

수행하고 나면 둘째 자리의 수를 반복해서 수행하는 식이다.

이 for문은 시간이 오래 걸릴 수 있는데 중간에 있는 모델을 훈련시키는 부분에 어떤 세팅을 하느냐에 따라 달라진다.

여기서는 첫째 자리에 대해 모델 훈련 후 첫째 자리 숫자를 예측하고 다시 둘째 자리의 데이터들을 통해 훈련을 하고 둘째 자리 숫자를 예측한다.

시간을 줄이려면 셋팅 값 중 batch_size나 epochs를 조정할 수 있고 또는 첫째 자리의 데이터로 훈련시킨 모델로 남은 5개의 번호를 예측해도 될 것이다.

어차피 로또 번호를 예측하는 정확도에는 둘 다 어떠한 영향을 주지 않을 것이기 때문이다.

 

이렇게 해서 나온 결과는 다음과 같다.

[array([[42.]], dtype=float32), array([[29.]], dtype=float32), array([[31.]], dtype=float32), array([[34.]], dtype=float32), array([[37.]], dtype=float32), array([[38.]], dtype=float32)]

 

 

여기까지 파이썬 딥러닝 중 LSTM을 이용하여 로또 당첨 번호를 예측하는 방법에 대해 2부에 걸쳐 알아봤다.

다음에는 데이터 학습을 하는 방법 말고 파이썬의 다른 시뮬레이션 기능, 예를 들면 물리적인 측면의 시뮬레이션을 통해 로또 번호를 예측할 수 있는 방법이 있는지 공부해 볼 계획이다.

잘 될지는 모르겠지만.....

 

반응형

댓글