이번주 로또번호는? 로또번호 데이터 분석
가끔 지인들과 로또가 되면 뭐하지?라는 말을 하곤 한다.
사실 모두들 로또가 되면 뭐하고 뭐하고 뭐해야지~ 하는 생각을 해봤을 거다ㅎㅎ
블로그들을 보다 아이디어를 얻어 재미 삼아 역대 로또번호들을 분석해봤다.
아래 url을 통해 시작했고 유사한 분석을 하신 분이 있다, 밑에 reference에 남기겠다.
코드는 깃헙에서 확인할 수 있다. https://github.com/keep-steady/bigdata_analysis/tree/master
1) 파이썬을 이용해 나눔 로또 API로 역대 로또번호들을 몽땅 가져온다
2) 이를 pandas를 이용하여 분석한다!!
1. 선언
우선 각종 library들을 import 한다. label은 로또를 긁어왔을 시 설명이다.
from urllib.request import urlopen
import pandas as pd
import json
import os
import matplotlib as mpl
import matplotlib.pyplot as plt
label = ['회차','추첨일','총판매금액','총1등당첨금','1등당첨게임수','게임당1등당첨금','1번번호','2번번호','3번번호','4번번호','5번번호','6번번호','보너스번호']
2. 로또 번호 가져오기
아래 코드는 www.nlotto.co.kr 에서 1~909회까지, 2002년 1월 27~2020년 5월 7일의 로또 정보들을 가져온 것이다.
이 글을 볼 때쯤 시간이 더 지나서 로또가 10000회까지 됐다면 910을 10001로 바꿔주면 된다.
dictionary로 들어온 lotto 변수를 list화 시키고 이를 pandas로 변환 후 csv 파일로 저장하였다.
한글 저장을 위해 db.to_csv의 인자에 encoding='utf-8-sig'를 추가한다. 이걸 안 하면 한글이 깨진다!!
history_list = []
for i in range(1, 910):
url="http://www.nlotto.co.kr/common.do?method=getLottoNumber&drwNo="+str(i)
result_data = urlopen(url)
result = result_data.read()
lotto = json.loads(result)
# list로 만들기
lotto_num = [lotto["drwNo"], lotto["drwNoDate"], lotto["totSellamnt"], lotto["firstAccumamnt"], lotto["firstPrzwnerCo"], lotto["firstWinamnt"], \
lotto["drwtNo1"], lotto["drwtNo2"], lotto["drwtNo3"], lotto["drwtNo4"], lotto["drwtNo5"], lotto["drwtNo6"], lotto["bnusNo"]]
history_list.append(lotto_num)
# pandas로 변환
db = pd.DataFrame(history_list, columns =label)
# csv 파일로 저장
db.to_csv("lotto_number_history.csv", header=True, encoding='utf-8-sig')
3. 저장한 DB 불러오기
위에서 저장한 csv파일을 pandas로 불러와 확인한다. 결과는 아래와 같다. 회차, 추첨일, 번호 등등이 나온다. 1등 당첨 게임수가 1등을 당첨된 사람 수이다. 그 회에 1등이 없으면 다음회에 누적하여 돈을 준다!!!
df=pd.read_csv("lotto_number_history.csv")
df.head(30)
4. 로또 빅데이터 분석
아래 명령어로 개수, 평균, 표준편차, 최대 최소 등의 간략한 통계정보를 얻을 수 있다.
pd.options.display.float_format = '{:,.12}'.format # 깔끔하게 나오게 하기 위해
df.describe()
5. 당첨 번호 분석
이 데이터들 중 관심 있는 로또 번호!!! 들만 모아서 통계정보를 보자
# 1~6번 번호만 가져오자
df_only_number=pd.DataFrame([df['1번번호'], df['2번번호'], df['3번번호'], df['4번번호'], df['5번번호'], df['6번번호']]).T
pd.options.display.float_format = '{:,.5}'.format # 깔끔하게 나오게 하기 위해
for i in range(1, 7):
print('%d 번 번호 평균 : %d' % (i, int(df_only_number.mean()[i-1])))
df_only_number.describe()
1 번 번호 평균 : 6
2 번 번호 평균 : 13
3 번 번호 평균 : 19
4 번 번호 평균 : 26
5 번 번호 평균 : 32
6 번 번호 평균 : 39
위 그림이 로또번호의 통계 정보이다. 신기한 사실은 당첨번호 간의 규칙이 있다. 1번과 2번의 차는 7, 2번과 3번의 차는 6, 그다음은 7, 그다음은 6, 7 인거다!!!
만약 로또를 사는데 통계정보, 평균을 이용해서 산다면 위 번호를 시도해보겠다..........................................?ㅋㅋㅋㅋ
6. 각 당첨번호 분포 분석
아래 코드를 이용하여 각 당첨번호들의 histogram을 그려보자
df_only_number['1번번호'].plot.hist(bins=45)
plt.title('1')
plt.show()
df_only_number['2번번호'].plot.hist(bins=45)
plt.title('2')
plt.show()
df_only_number['3번번호'].plot.hist(bins=45)
plt.title('3')
plt.show()
df_only_number['4번번호'].plot.hist(bins=45)
plt.title('4')
plt.show()
df_only_number['5번번호'].plot.hist(bins=45)
plt.title('5')
plt.show()
df_only_number['6번번호'].plot.hist(bins=45)
plt.title('6')
plt.show()
아래 그림은 1~6번 당첨번호의 숫자 빈도수 그래프이다. 신기한 건 그래프들이 가우시안이나 normal 분포가 아니었다. 어떤 분포인지 찾아보려다가 말았다.
7. 1등 당첨 숫자
아래 코드로 그 회에 1등이 몇 번 당첨됐는지를 확인해봤다.
df['1등당첨게임수'].plot(figsize=(20,6),color = 'blue')
plt.plot(list(range((len(df['1등당첨게임수'])+2))), [df['1등당첨게임수'].mean()]*(len(df['1등당첨게임수'])+2), 'red')
plt.title('num of 1st')
plt.show()
1등이 한 번도 당첨되지 않은 횟수도 많았지만 한 회에 30명 가까이 1등이 나온 적도 있었다. 와!! 1등이 30명이라니
평균 1회 7명씩 당첨이 됐다. 그럼 10년간 여태 6,279명의 1등이 탄생한 것이다!!!! 5천만 인구 중 6천 명은 1등에 당첨돼 봤다. 생각보다 많은데??? 확률상은 1만 명 중 1명씩 1등이네?
8. 총판매금액 추이
df['총판매금액'].plot(figsize=(20,6),color = 'b')
plt.plot(list(range((len(df['총판매금액'])+2))), [df['총판매금액'].mean()]*(len(df['총판매금액'])+2), 'red')
plt.title('num of 1st')
plt.show()
2002년부터 지금까지 로또 판매 금액이다. 1주일에 평균 590억 어치의 로또가 팔린다 세상에. 초반에 확실히 로또 열풍이 심했다. 그러다 점점 떨어졌지만 또 증가하는 추세이다.
9. 숫자별 평균 개수
numm_tmp = pd.concat([df_only_number['1번번호'], df_only_number['2번번호'], df_only_number['3번번호'], df_only_number['4번번호'], df_only_number['5번번호'], df_only_number['6번번호']])
numm_tmp1 = numm_tmp.value_counts().sort_index()
print('평균 갯수 : %.0f' % (numm_tmp1.mean()))
plt.plot(numm_tmp1)
plt.plot(list(range((len(numm_tmp1)+2))), [121]*(len(numm_tmp1)+2), 'red')
plt.title('frequency')
plt.show()
1~45 숫자 달은 모두 평균 121번씩 나왔다. 근데 그중 유독 안 나온 숫자들이 있다!!!
[9, 22, 23, 29, 32, 41] 이 6개의 숫자들은 다른 숫자들에 비해 너무 안 나왔다. 만약 큰 수의 법칙(Law of Large Number)을 믿는다면 위 번호들로 도전해 보자. 로또를 엄청 많은 회차로 진행한다면(무한대 or 100,000 이상) 샘플 평균이 모집단의 평균이 된다. 즉 계속할수록 작은 녀석들이 많이 나올 수도??
print('많이 나온 숫자들 : %s\n\n%s' % (list(numm_tmp1.sort_values()[39:].keys().sort_values()), numm_tmp1.sort_values()[:6]))
또 많이 나오는 숫자들은 또 나오지 않을까?라고 접근한다면 위 코드를 수행하여 많이 나온 숫자들을 확인해보자.
많이 나온 숫자들 : [17, 18, 27, 34, 40, 43]
많이 나왔으니 계속 또 나오려나? 아님 이제 안 나오려나
Discussion
지금까지 로또 당첨 빅데이터를 통계적으로 분석했다. 로또는 매번 완전 랜덤이다. 그러므로 지금까지 분석한 과거의 데이터로 미래를 예측할 수 없다. 종속이 아니라 완전 독립이므로 이번 주 로또를 알 수 있는 건 불가능하다!!!!
그냥 재미로 아~~~ 오오? 그래? 정도까지로 멈추자. 진지하게 큰 수의 법칙은 어떤 상황에서 성립하고 안 하고 이런 건 하지 말자. 그냥 재미로 여기까지!! 혹시 아는가?ㅎㅎ
Reference
1. https://stricky.tistory.com/158?fbclid=IwAR0oy9AjkpHJ7g3SM7muNlk7pbyxSiKPFeQ4lpCCnSB2ESOwg4ID9rBaclY
2. https://somjang.tistory.com/entry/Python%EB%A1%9C%EB%98%90-api%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%98%EC%97%AC-%EC%97%AD%EB%8C%80-%EB%A1%9C%EB%98%90-%EB%8B%B9%EC%B2%A8-%EA%B2%B0%EA%B3%BC-%EB%B6%84%EC%84%9D%ED%95%B4%EB%B3%B4%EA%B8%B0?category=345065