
부자가 되겠다 !
로또 번호를 분석해 예측한다는 말 자체가 어쩌면 어리석은 일일지도 모릅니다.
솔직히 저도 압니다. 로또라는 건 완전한 우연이고, 운명과도 같은 확률의 영역이라, 논리적으로 분석하거나 예측할 수 없다는 걸 말입니다.
하지만 가끔 사람은 불가능한 일에도 작은 희망을 걸곤 합니다. 확
률과 이성을 잠시 내려놓고, '혹시…?' 하는 아주 작은 가능성에 기대어 보는 거죠.
이 글 역시 그런 감성에서 출발합니다.
여기서 철저히 논리는 배제할 것입니다. 대신, 아주 작은 가능성과 호기심만을 따라가는 여정이 될 것입니다. 말도 안 되는 일을 시도한다는 걸 알지만, 그럼에도 불구하고 설레는 마음으로 시작해 보겠습니다.
1.동행복권 데이터 가져오기
2. 1회부터 1164회까지 데이터 가져오기
import pandas as pd
df = pd.read_excel("/content/drive/MyDrive/project/1164_lotto_corrected.xlsx")
df
1회차부터 1164회차까지 (2025년 03월 22일까지) 자료 입니다
3.번호 빈도수 분석
# 모든 회차의 당첨 번호(보너스 제외)를 하나의 리스트로 합침
all_numbers = df[['번호1', '번호2', '번호3', '번호4', '번호5', '번호6']].values.flatten()
# 숫자별 등장 횟수 계산
number_counts = pd.Series(all_numbers).value_counts().sort_values(ascending=False)
# 상위 6개 번호 추출
top_6_numbers = number_counts.head(6).index.tolist()
top_6_numbers
🎯 가장 많이 나온 로또 번호 TOP 10
순위 | 번호 | 등장 횟수 |
---|---|---|
1 | 34 | 179회 |
2 | 12 | 170회 |
3 | 13 | 169회 |
4 | 18 | 168회 |
5 | 45 | 167회 |
6 | 33 | 166회 |
7 | 27 | 166회 |
8 | 14 | 165회 |
9 | 40 | 163회 |
10 | 37 | 163회 |
빈도수 상위 6개로 번호 하나 완성
[34, 12, 13, 18, 45, 33]
4.머신러닝 활용
이전 회차의 번호들을 보고, 다음 회차에 어떤 숫자가 나올지 하나씩 예측
랜덤포레스트(Random Forest) 같은 머신러닝 모델에 학습시켜
"다음엔 어떤 번호가 나올지"를 예측해보기
1, 5, 10, 20, 30, 40 | 예측번호 : 10 |
이런 식으로 데이터를 만들어서 머신러닝 모델에게 학습시켜.
즉, "이런 번호들이 나오면, 다음엔 이런 숫자가 나올 확률이 높아!" 를 배우게 하는 모델
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
import numpy as np
# 전체 번호 조합 (보너스번호 제외)
lotto_numbers = df[['번호1', '번호2', '번호3', '번호4', '번호5', '번호6']].values
# 예측 대상 번호: 1부터 45까지 하나씩
number_range = range(1, 46)
# 결과 저장용 딕셔너리
predicted_probs = {}
# 각 번호에 대해 "다음 회차에 등장 여부"를 예측
for target_number in number_range:
X = []
y = []
for i in range(len(lotto_numbers) - 1):
# 입력: i번째 회차의 번호 6개
X.append(lotto_numbers[i])
# 출력: i+1번째 회차에 target_number가 나왔는지 (1 또는 0)
y.append(1 if target_number in lotto_numbers[i + 1] else 0)
X = np.array(X)
y = np.array(y)
# 훈련/검증 데이터 분리
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 랜덤포레스트 분류 모델
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
# 최신 회차 데이터로 예측
latest_data = lotto_numbers[-1].reshape(1, -1)
prob = model.predict_proba(latest_data)[0][1] # target_number이 나올 확률
predicted_probs[target_number] = prob
# 확률이 높은 순으로 정렬하여 상위 6개 추출
top_predicted_numbers = sorted(predicted_probs.items(), key=lambda x: x[1], reverse=True)[:6]
top_predicted_numbers
예측 번호 | 등장 확률 |
---|---|
34 | 39% |
40 | 28% |
6 | 27% |
13 | 26% |
18 | 26% |
44 | 25% |
랜덤으로 숫자가 추첨되다보니 패턴이없어
빈도수로 출력된값과 거창하게 랜덤포레스트를 돌린것과 큰 차이가 없다는 것
5. 패턴으로 숫자 예측( LSTM 기반 )
LSTM(Long Short-Term Memory)은 과거의 데이터를 기억하면서 현재와 미래를 예측하는 데 사용하는 딥러닝 기술의 일종입니다. 쉽게 말해, LSTM은 일종의 '기억력 좋은 인공지능'
무작위에 가까운 패턴 속에서도 흐름의 경향을 캐치할 수 있는 모델
최근 10~20회차로 시퀀스를 구성해서 LSTM 모델을 학습
import numpy as np
import pandas as pd
from sklearn.preprocessing import MultiLabelBinarizer
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
# 엑셀 불러오기
df = pd.read_excel("1164_lotto_corrected.xlsx")
lotto_data = df[['번호1', '번호2', '번호3', '번호4', '번호5', '번호6']].values.tolist()
# 시퀀스 길이
N = 10
# One-hot encoding
mlb = MultiLabelBinarizer(classes=list(range(1, 46)))
mlb.fit(lotto_data)
binary_data = mlb.transform(lotto_data)
# 시퀀스 데이터 생성
X_seq = []
y_seq = []
for i in range(len(binary_data) - N):
X_seq.append(binary_data[i:i+N])
y_seq.append(binary_data[i+N])
X_seq = np.array(X_seq)
y_seq = np.array(y_seq)
# LSTM 모델 구성
model = Sequential([
LSTM(64, input_shape=(N, 45), return_sequences=False),
Dense(45, activation='sigmoid') # 각 번호의 등장 확률
])
model.compile(optimizer='adam', loss='binary_crossentropy')
# 모델 학습
model.fit(X_seq, y_seq, epochs=30, batch_size=8, verbose=1)
# 최신 10회차로 다음 번호 예측
latest_seq = binary_data[-N:].reshape(1, N, 45)
predicted_probs = model.predict(latest_seq)[0]
# 확률이 높은 상위 6개 번호 추천
top_6 = np.argsort(predicted_probs)[-6:][::-1] + 1
print("🎯 LSTM 기반 예측 추천 번호:", top_6.tolist())
숫자가 어떻게 나오나 3번 실행한결과
예측 결과 :
[11, 15, 29, 2, 37, 19]
[3, 42, 36, 21, 13, 19]
[39, 18, 41, 20, 35, 15]
회차별로 숫자가 겹치는것을 발견 ..
매주, 로또를 일주일에 5천 원 정도,
딱 5줄 구매하는 편이다.
물론 알지만, 로또는 완전한 확률 게임이다.
예측도, 전략도, 모두 운 앞에서는 작아질 수밖에 없다.
하지만 그렇다고 무작정 아무 번호나 고르기엔 아쉬운 마음이 드는 것도 사실이다.
그래서 나는 하나의 원칙을 정했다.
"각 회차(줄)별로 겹치는 숫자를 넣지 않는다."
이유는 단순하다.
실제로 당첨 확률이 높아지는 건 아니겠지만,
적어도 리스크는 분산된다.
- 하나의 번호에 모든 기대를 거는 것보단
- 서로 다른 번호를 고르면,
- 다양한 조합이 당첨 번호와 맞물릴 확률이 조금은 생긴다.
이번에 만든 로또 예측 시스템도 그것을 적용시킬 생각이다.
LSTM 딥러닝 모델을 통해 다음 5회차(=5줄)를 예측했지만,
예측 결과에 나오는 번호들끼리 겹치지 않도록 구성했다.
한 회차에 6개 번호씩, 총 30개.
서로 다른 숫자로 구성된 5개의 추천 세트.
6. LSTM 기반 로또 번호 예측 (다음 5회차, 중복 없이 30개 분배)
import numpy as np
import pandas as pd
from sklearn.preprocessing import MultiLabelBinarizer
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, TimeDistributed, RepeatVector
# ✅ 1. 엑셀 파일 불러오기
lotto_data = df[['번호1', '번호2', '번호3', '번호4', '번호5', '번호6']].values.tolist()
# ✅ 2. 파라미터 설정
N = 10 # 입력 시퀀스 길이 (최근 10회)
future_steps = 5 # 예측할 미래 회차 수
# ✅ 3. One-hot 인코딩 (1~45 번호)
mlb = MultiLabelBinarizer(classes=list(range(1, 46)))
mlb.fit(lotto_data)
binary_data = mlb.transform(lotto_data)
# ✅ 4. 입력(X)과 출력(y) 시퀀스 생성
X_seq, y_seq = [], []
for i in range(len(binary_data) - N - future_steps + 1):
X_seq.append(binary_data[i:i+N]) # (10, 45)
y_seq.append(binary_data[i+N:i+N+future_steps]) # (5, 45)
X_seq = np.array(X_seq)
y_seq = np.array(y_seq)
# ✅ 5. LSTM 모델 구성
model = Sequential([
LSTM(64, input_shape=(N, 45)),
RepeatVector(future_steps),
LSTM(64, return_sequences=True),
TimeDistributed(Dense(45, activation='sigmoid'))
])
model.compile(optimizer='adam', loss='binary_crossentropy')
# ✅ 6. 모델 학습
model.fit(X_seq, y_seq, epochs=30, batch_size=8, verbose=1)
# ✅ 7. 최신 10회차로 예측
latest_seq = binary_data[-N:].reshape(1, N, 45)
predicted_probs_5 = model.predict(latest_seq)[0] # shape: (5, 45)
# ✅ 8. 전체 확률 합산 → 중복 없이 상위 30개 추출
total_probs = predicted_probs_5.sum(axis=0) # shape: (45,)
top_30_indices = np.argsort(total_probs)[-30:][::-1] + 1 # 1부터 시작
# ✅ 9. 5세트로 분배 (6개씩)
unique_5_sets = [top_30_indices[i*6:(i+1)*6].tolist() for i in range(5)]
# ✅ 10. 결과 출력
print("\n🎯 [LSTM 기반 로또 예측] 중복 없는 5세트 추천 번호")
for i, nums in enumerate(unique_5_sets):
print(f"회차 {i+1}: {sorted(nums)}")
딥러닝 모델이 학습을 시작하고, 에포크가 하나씩 지나갈수록
문득 이런 생각이 들었다.
“랜덤성에서 의미를 찾는 게 과연 가능할까?”
애초에 알고 있었다.
로또는 운의 영역이고, 데이터 속에서 당첨을 예측하는 건
정답이 없는 도전이라는 걸.
그럼에도 불구하고
이걸 굳이 LSTM까지 써가며 해야 했나? 싶은 순간이 찾아왔다.
하지만 곧 생각을 바꿨다.
그래도 이번에 LSTM이 어떻게 작동하는지 배웠고,
예측 흐름을 시도해보는 과정 자체가 값진 학습이었다.
5세트 번호 예측결과
회차 | 번호 1 | 번호 2 | 번호 3 | 번호 4 | 번호 5 | 번호 6 |
---|---|---|---|---|---|---|
1 | 12 | 33 | 36 | 37 | 38 | 39 |
2 | 11 | 15 | 18 | 19 | 25 | 28 |
3 | 2 | 4 | 17 | 21 | 24 | 31 |
4 | 6 | 9 | 10 | 13 | 42 | 43 |
5 | 3 | 16 | 29 | 30 | 44 | 45 |
5천원 로또를 구매해서 이번주에 확인해보도록 하겠습니다
글 읽어주셔서 감사합니다