본문 바로가기
Python

PROPHET 머신 러닝을 이용한 파이썬 로또 번호 생성

by 아짱이아빠 2021. 6. 6. 15:00
반응형

이번에 파이썬의 머신 러닝 중 PROPHET 알고리즘을 이용하여 로또 번호 6자리를 추출하는 프로그램에 대해 얘기해 보겠다.

 

내 블로그에는 아래처럼 이전에 파이썬 머신 러닝을 이용하여 다음번 로또 번호 6자리의 총합을 예측하고 예측된 합을 만족하는 6자리의 번호는 과거 가장 많이 나왔던 번호 순데로 조합을 하거나 가장 적게 나온 순데로 조합을 하는 방식에 대해 공부한 내용을 소개했었다.

 

 

 

Python Machine Learning을 이용한 Lotto 번호 생성 프로그램 - (1)

이번에 파이썬을 이용하여 Lotto 번호 6자리를 뽑아내는 프로그램을 만들어 보았다. 많은 사람들이 Lotto 번호를 만드는 프로그램을 만들었으며 대부분은 random() 함수를 이용하여 난수를 생성한다.

superhky.tistory.com

 

 

Python Machine Learning을 이용한 Lotto 번호 생성 프로그램 - (2)(UPDATE - 2021.05.01)

1부에서 Machine Learning을 통해 다음 차수의 1등 Lotto 번호 총 합 예측을 하였다. 2부에서는 예측된 합에서 6개의 Lotto 번호 조합을 찾아보도록 하겠다. 1부 처음에 얘기했듯이 Lotto 번호의 조합은 과

superhky.tistory.com

 

이번에는 PROPHET이라는 머신 러닝 알고리즘을 이용해서 지난번과 동일하게 다음 당첨 번호의 총합을 예측한다.

그리고 1부터 45까지의 숫자를 랜덤으로 생성하여 예측된 합을 만족하는 6자리의 숫자를 뽑아내는 것이다.

 

지난번의 가장 많이 나왔던 숫자의 순으로 조합을 하거나 가장 적게 나왔던 순으로 숫자를 만드는 것은 처음에 숫자의 합이 130~160 이내에서는 잘 작동했는데, 예측된 합이 100 이하 이거나 170을 넘거나 하는 경우에 여러 가지의 문제점이 발견되었다.

한 번 해보시면 아시겠지만 프로그램 초보자 입장에서 이게 쉽지 않은 문제이다.

내 프로그래밍 실력이 부족한 것도 있고 시간이 없는 문제도 있고 아무튼 더 이상은 오류를 잡아내는 것은 포기하고 다른 방식을 적용하게 되었다.

(몇몇 분께서 지난 블로그에 있는 글을 보시고 로또 번호 조합을 찾는 코드를 보여달라고 하셨었는데 위와 같은 사유로 그러지 못했음을 이해해 주시길 바랍니다.) 

 

먼저 PROPHET는 Facebook에서 만든 시계열 예측 알고리즘이다.

아주 쉽게 다룰 수 있도록 되어 있어서 적용하게 되었고 이 알고리즘으로 다음 회차의 로또 당첨 번호들의 총합을 예측할 것이다.

 

가장 먼저 하는 것은 그동안의 로또 당첨 번호를 다운로드하는 것이다.

이 부분은 위의 링크에 있는 이전 글에서 다루었으므로 넘어가도록 하겠다.

 

다운로드한 로또 데이터는 “lotto_df”에 저장한다.

다운로드한 로또 데이터에서 각 회차의 1등 당첨번호 숫자 합을 구하여 "data_sum" 변수에 저장하고 다시 값만을 "values" 변수에 저장한다.

data_sum = lotto_df["Num1"]+lotto_df["Num2"]+lotto_df["Num3"]+lotto_df["Num4"]+lotto_df["Num5"]+lotto_df["Num6"]
values = data_sum.values

 

다음이 PROPHET 알고리즘으로 예측을 수행하는 부분이다.

from fbprophet import Prophet
import pandas as pd
new_values=[]
new_values = pd.DataFrame(new_values)
new_values['ds'] = lotto_df['추첨일']
new_values['y'] = values
data = new_values[['ds','y']]

 

먼저 필요한 라이브러리를 불러온 후 "new_values"라는 빈 행렬을 만들고 이를 다시 dataframe 형식으로 바꾸어 주었다.

PROPHET은 아주 간단하게 "ds" column에 날짜를 넣고 "y" column에 값을 넣은 후 이 데이터를 훈련시키기만 하면 된다.

위에서 최초 다운로드한 로또 데이터에서 ‘추첨일’에 있는 날짜를 "ds"에 넣어주고 앞에서의 로또 번호들의 합들을 "y"에 넣어주었다.

 

다음의 코드들을 통해 모델을 만들고 예측을 하여 forecast에 예측된 정보들을 저장한다.

model=Prophet()
model.fit(data)
future = model.make_future_dataframe(periods=168, freq='H')
forecast = model.predict(future)

여기서 일주일마다 로또를 추첨하므로 perioids에는 168시간을 입력하였다. 

 

forecast를 출력해보면 예측된 값의 트렌드나 최솟값, 최댓값 등 다양한 정보가 있는데 우리가 관심 있는 예측 결과는 맨 뒤에 있는 "yhat" column의 값들이다.

 

또한, 다음의 명령을 통해 결과를 그림으로 확인할 수 있다.

fig1=model.plot(forecast)
fig2=model.plot_components(forecast)

PROPHET 결과-1
PROPHET 결과-1
PROPHET 결과-2
PROPHET 결과-2

 

그래서 이를 마무리 지어보면 아래의 코드로 예측값을 얻게 된다.

forecast_1 = forecast['yhat'].values[len(forecast)-1]
print('The Prophet Predicted Value :', forecast_1)

"forecast"에 있는 "yhat" column의 마지막 값을 "forecast_1" 변수에 넣고 이를 출력한다.

 

 

다음은 예측된 합을 구성하는 6자리 번호의 조합을 만들어내는 것이다.

앞에서도 얘기했듯이 가장 많이 나왔던 수나 가장 적게 나왔던 수와 상관없이 랜덤으로 45개 숫자를 생성한 후 합을 만족하는 6자리 숫자를 뽑는다.

 

전체적인 구성은 다음과 같다.

1부터 45까지 래덤으로 추출한 숫자들 한 세트 만들고 앞에서부터 하나씩 숫자를 더하면서 예측된 합이 되는지 맞춰본다.

만약 숫자 6개가 안되었는데 합을 만족한다든지 합을 넘는다든지 아니면 6개가 되어도 합보다 부족하든지 하는 상황들을 체크하면서 진행한다.

한 번의 45개의 숫자 세트로 합을 만족하는 6개 숫자를 뽑지 못하면 다시 랜덤으로 1부터 45개 숫자를 만들어야 하고 위의 과정을 계속한다.

 

완성된 코드는 아래와 같으며 보다시피 if문 안에 또 if문이 있고 좀 무식하게 만들었으며 아무튼 깔끔해 보이진 않는다.

프로그램 전공자도 아니고 남는 시간에 파이썬을 배워가는 입장에서 이렇게밖에 할 수 없는 것을 이해해주길 바란다. 

 

import random

pre_sum=int(input("숫자를 입력하세요 :"))

while True:
  ran = []
  sum=0
  pre_number=[]
  for i in range(1,46):
    ran.append(i)
  
  random.shuffle(ran)

  for i in range(45):
    ran_a = ran[i]
    sum = sum + ran_a
    pre_number.append(ran_a)
    if len(pre_number) == 2:
      if sum >= pre_sum:
        pre_number.remove(ran_a)
        sum = sum-ran_a

    if len(pre_number) == 3:
      if sum >= pre_sum:
        pre_number.remove(ran_a)
        sum = sum-ran_a

    if len(pre_number) == 4:
      if sum >= pre_sum:
        pre_number.remove(ran_a)
        sum = sum-ran_a

    if len(pre_number) == 5:
      if sum >= pre_sum:
        pre_number.remove(ran_a)
        sum = sum-ran_a

    if len(pre_number) == 6:
      if sum > pre_sum:
        pre_number.remove(ran_a)
        sum = sum-ran_a
      elif sum < pre_sum:
        pre_number.remove(ran_a)
        sum = sum-ran_a
      elif sum == pre_sum:
        break

  if len(pre_number) == 6 :
    break

위를 실행시키면 PROPHET에서 예측한 합을 직접 입력하게 되어 있고 입력 후 결과가 나온다.

로또 결과 예
(결과 예)

 

결론이다.

오래전부터 가능한 매주 오천 원씩 로또를 구매했는데 그 당시 아무 번호나 적거나 또는 자동으로 할 때 보다 올해 초부터 이러한 방식으로 로또를 구매했을 때(예전과 똑같이 오천 원씩) 5등 당첨률이 눈에 띄게 높아졌다.

물론 전적으로 운이었겠지만 그래도 왠지 뿌듯함은 있다.

 

 

 

반응형

댓글