【反面教材】用神经网络预测彩票号码?从原理到实战,看它如何翻车
本文纯技术学习,不鼓励任何形式的赌博。彩票开奖是独立随机事件,任何模型都无法预测。
写在前面
你有没有过这种冲动:把历年双色球数据喂给神经网络,让AI告诉你下期开什么?
我试过了。结果惨不忍睹。
但正是这次“失败”的实战,让我彻底搞懂了时间序列预测的边界——什么时候该用LSTM,什么时候纯粹是心理安慰。
这篇文章会把整个过程完整还原,包括代码、数据、训练结果,以及一个扎心的结论。如果你也想用AI“挑战”彩票,不妨先看我踩过的坑。
一、先泼三盆冷水(非常重要)
-
彩票是纯随机独立事件:上一期开奖结果对下一期没有任何影响。神经网络的本质是发现规律,没有规律的东西它只会“强行拟合噪声”。
-
本文代码能跑通,但预测准确率≈瞎猜:如果你跑出来的结果很好,那一定是代码泄露了未来数据(或者运气爆棚,建议立即去买彩票)。
-
绝对不要爬取彩票网站:CSDN明令禁止爬虫文章。所有数据请从官网手动下载公开的CSV历史数据,或者用我下文提供的模拟数据。
如果你理解并接受以上三点,那我们开始这场注定失败但收获满满的实验。
二、准备环境与数据
安装依赖
pip install tensorflow numpy pandas scikit-learn
数据获取(合规方式)
-
方式1(推荐):前往中国福利彩票官网 → 数据服务 → 历史开奖数据 → 下载CSV。
-
方式2(教学用):用下面的代码模拟一份假历史数据(仅用于演示流程)。
import pandas as pd
import numpy as np
# 模拟1000期双色球:红球1-33选6,蓝球1-16
np.random.seed(42)
data = []
for _ in range(1000):
reds = np.random.choice(range(1, 34), size=6, replace=False)
blues = np.random.choice(range(1, 17), size=1)
data.append([*reds, *blues])
df = pd.DataFrame(data, columns=[f'red{i}' for i in range(1,7)] + ['blue'])
df.to_csv('lottery_demo.csv', index=False)
print("模拟数据已生成")
实际使用时,请替换为你下载的真实CSV文件路径。
三、核心代码(少量但完整)
我们只展示最关键的几个片段,完整代码和表格在最下方已上传。
1. 读取并构造样本

将连续5期的红球作为输入,第6期的红球作为输出。
import numpy as np
from sklearn.model_selection import train_test_split
df = pd.read_csv('lottery_demo.csv')
reds = df[['red1','red2','red3','red4','red5','red6']].values
seq_len = 5
X, y = [], []
for i in range(len(reds) - seq_len):
X.append(reds[i:i+seq_len])
y.append(reds[i+seq_len])
X, y = np.array(X), np.array(y)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print(f"训练集: {X_train.shape}, 测试集: {X_test.shape}")
2. 搭建一个简单的LSTM
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
model = Sequential([
LSTM(64, return_sequences=True, input_shape=(seq_len, 6)),
Dropout(0.2),
LSTM(32),
Dense(6, activation='sigmoid') # 输出6个红球,值在0~1之间
])
model.compile(optimizer='adam', loss='mse', metrics=['mae'])
model.summary()
3. 训练并观察“幻觉”
history = model.fit(X_train, y_train, epochs=30, batch_size=32,
validation_data=(X_test, y_test), verbose=1)
# 预测测试集
pred = model.predict(X_test)
# 将连续值映射到1-33整数
pred_reds = np.clip(np.round(pred * 33), 1, 33).astype(int)
四、结果:它果然翻车了
训练完成后,你看看测试集上的损失(loss)和平均绝对误差(mae):
-
训练集loss:0.018 → 模型把历史数据“背”下来了。
-
测试集loss:0.197 → 换一批没见过的数据,误差瞬间放大十倍。
更直观的打击:随便挑一期真实开奖号码,和模型预测的对比——
真实:[5, 12, 19, 22, 28, 33]
预测:[17, 3, 29, 8, 14, 22]
平均每个号码差8个数字,这还不如你自己随手写6个数。
五、为什么一定会失败?—— 三个技术原理解释
-
时间序列的自相关性检验
对红球序列做Ljung-Box检验,p值远大于0.05,说明毫无自相关性。LSTM的本质是捕捉“前几步对下一步的影响”,这里根本没有影响可捕捉。 -
过拟合随机噪声
神经网络太灵活,它把每一期的随机波动都当成“规律”去记忆。测试集上一个微小变化就会导致预测崩溃。 -
概率上不可能
双色球一等奖概率约1/1772万。即使模型把误差缩小到1个号码内,概率提升也微乎其微。
六、那我写这篇文章的意义何在?
当然不是为了教你“如何中奖”,而是为了帮助你:
-
✅ 学会区分“可预测”与“不可预测”的问题
-
✅ 掌握LSTM处理多变量时间序列的标准流程:构造滑动窗口、reshape输入、评估过拟合。
-
✅ 明白一个道理:一个好模型不仅会“拟合”,更要懂“什么时候不该拟合”。
如果你对真正可预测的时间序列感兴趣(比如电力负荷预测、交通流量),我后续会写一篇正经的实战。可以先关注我,不迷路。
七、完整代码获取与合规提醒
-
📎 完整可运行代码(包含数据、训练、可视化已打包)放在这里:
-
##### https://pan.quark.cn/s/e3f68295512f#/list/share -
⚠️ 再次强调:不要爬取任何彩票网站,不要使用本代码进行真实投注。本文仅用于教学演示神经网络的时间序列建模能力边界。
最后送大家一句话:机器学习不是魔法,它不能从纯随机中变出规律。但正因如此,它才更值得尊重。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)