《LSTM神经网络和双色球预测例子》

前言:
书接上回,通过把历年来的双色球蓝球数据爬取,可以看出,每期双色球蓝球之间并无任何关系,但仍存在问题:
决定蓝球数字可能并非取决于上一期蓝球的数据,可能取决于当期红球的数据,我们可能需要通盘考虑红球数据和蓝球数据。

那这期的任务就是:使用红球和蓝球数据作为训练集来训练神经网络,把上期双色球的数字来预测下期双色球的数字。

目标:
1、如果模型预测有效,(好家伙,发财了) 证明我们的搭建模型的方法存在问题。
2、如果模型预测无效,证明LSTM神经网络对于无规律数据的预测是无能为力的。

LSTM神经网络:
LSTM神经网络(长短时记忆神经网络)是RNN网络的一种变种,起初是为了解决RNN网络的很难有效利用历史记忆的问题而提出来的,在实践中证明,这一变种的神经网络能非常有效地利用历史数据来从中学习数据的规律。
在这里插入图片描述
LSTM网络的有三个门:记忆门输出门遗忘门
在这里插入图片描述
其中,记忆门是由输入门(input gate)和tanh神经网络层和一个按位乘操作组成。作用是根据当前的输入和上面传递下来的信息来选择哪些信息需要被保留。

遗忘门的作用就是用来选择历史信息中哪些是有用的,哪些是需要被抛弃的。

输出门的作用就是把前面遗忘门与记忆门计算后的细胞状态, 与上一时刻的输出信号和当前时刻的输入信号整合到一起作为当前时刻的输出信号。传递给下一时刻。

绕晕了没关系,总之LSTM神经网络能很好地从历史数据中挖掘出需要的特征,所以关于时间序列的数据有不错的效果,在工业应用中的效果很好。

双色球预测:

1、数据爬取:
神经网络最重要的东西就是数据,没有数据,一切都是白搭,因此我们先把数据完整地从网站中用爬虫爬下来。
网站依旧是500彩票网。
期数一共是2668期。
爬虫代码根据上一次代码,修改了一点,加入了try语句,防止网络不好导致爬取失败,连续三次出错就会返回error。

import urllib.request
import pandas as pd

bull_data = []


def url_pachong():
    global test, bull_data
    blue_list = [89, 122, 153, 154, 153, 154, 154, 153, 154, 154, 154, 152, 154, 153, 154, 153, 151, 134, 24]
    for i in range(19):
        for j in range(blue_list[i]):
            attempts = 0
            success = False
            data = []
            while attempts < 3 and success == False:
                try:
                    if i < 7:
                        response = urllib.request.urlopen(
                            "https://kaijiang.500.com/shtml/ssq/0" + str((i + 3) * 1000 + 1 + j) + ".shtml")
                        print(str((i + 3) * 1000 + 1 + j))
                    else:
                        response = urllib.request.urlopen(
                            "https://kaijiang.500.com/shtml/ssq/" + str((i + 3) * 1000 + 1 + j) + ".shtml")
                        print(str((i + 3) * 1000 + 1 + j))
                    if (i + 3) * 1000 + 1 + j == 17001:
                        success = True
                        continue
                    html = response.read().decode("gbk", "ignore")
                    a = 0
                    for k in range(6):
                        html_data = html.find('<li class="ball_red">', a + 10)
                        a = html_data
                        data.append(int(html[html_data + 21] + html[html_data + 22]))
                    html_data = html.find('<li class="ball_blue">')
                    data.append(int(html[html_data + 22] + html[html_data + 23]))
                    bull_data.append(list(data))
                    success = True
                except:
                    attempts += 1
                    print('error')
                    if attempts == 3:
                        break
        print(bull_data)
        print("阶段%d完成" % int(i + 3))


if __name__ == "__main__":
    url_pachong()
    test = pd.DataFrame(columns=['red1', 'red2', 'red3', 'red4', 'red5', 'red6', 'blue'], data=bull_data)
    test.to_csv('C:/Users/小幻月/Desktop/双色球数据爬取/bull_data2_c.csv')

爬取出来的数据保存到我自己桌面的文件夹里,需要的话可以自行更改。
在这里插入图片描述
爬取的数据如图所示。

2、LSTM神经网络训练
关于LSTM神经网络我们使用Tensorflow进行模型的搭建,Tensorflow可以很好地支持用Python进行模型的搭建。

但在使用模型进行预测前,我们需要对数据进行一些处理,一共需要做的有两步:
1、需要把原始数据划分成训练集和测试集,训练集用于对模型进行训练,测试集用于对模型效果的检验。
2、神经网络的输入需要我们构建一个三维的张量,目前的数据读取出来仅仅只是二维,需要对数据进行升维。

代码如下所示:

from pandas import read_csv
from pandas import DataFrame
from pandas import concat
from matplotlib import pyplot
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import Dropout


def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    n_vars = 1 if type(data) is list else data.shape[1]
    df = DataFrame(data)
    cols, names = list(), list()
    # input sequence (t-n, ... t-1)
    for i in range(n_in, 0, -1):
        cols.append(df.shift(i))
        names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
    # forecast sequence (t, t+1, ... t+n)
    for i in range(0, n_out):
        cols.append(df.shift(-i))
        if i == 0:
            names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
        else:
            names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
    # put it all together
    agg = concat(cols, axis=1)
    agg.columns = names
    # drop rows with NaN values
    if dropnan:
        agg.dropna(inplace=True)
    return agg


if __name__ == "__main__":
    #数据的读取和处理
    dataset = read_csv('bull_data2_c.csv', index_col=0)
    dataset.index.name = 'data'
    values = dataset.values
    values = values.astype('float32')
    scaler = MinMaxScaler(feature_range=(0, 1)) #归一化
    scaled = scaler.fit_transform(values)
    reframed = series_to_supervised(scaled, 1, 1) #转变为监督学习
    values_ss = reframed.values
    train_data = 2500 #训练集数目
    #划分训练集和测试集
    train = values_ss[:train_data, :]
    test = values_ss[train_data:, :]
    train_X = train[:, :7]
    train_Y = train[:, 7:]
    test_X = test[:, :7]
    test_Y = test[:, 7:]
    #升维成三维张量
    train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
    test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
    #模型搭建
    model = Sequential()
    model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))
    model.add(Dense(7))
    model.add(Dropout(0.25))
    model.compile(loss='mean_squared_error', optimizer='adam')
    model.fit(train_X, train_Y, epochs=50, batch_size=1, validation_data=(test_X, test_Y), verbose=1, shuffle=False)
    model.save("my_model.h5")
    #利用模型进行预测
    yhat = model.predict(test_X)
    yhat_change = scaler.inverse_transform(yhat)
    test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
    test_Y = scaler.inverse_transform(test_Y)
    for i in range(test_X.shape[0]):
        pyplot.plot(yhat_change[i])
        pyplot.plot(test_Y[i])
    pyplot.show()

由代码中可以看到,我们把前2500期作为训练数据,剩下的作为测试集。

其中有个子程序series_to_supervised,这个程序的作用是把数据变为监督学习所用,效果就是会把下一行的数据当做上一行数据输入的结果,建立起因果关系去告诉模型按这个输入输出来学习。
具体可以参考文章:
浅笑古今:将时间序列预测问题转换为python中的监督学习问题
其输出结果是一个长2666宽14的矩阵,我们把前7列剪出来作为输入,后7列剪出来作为输出结果。
再把前2500行剪出来作为训练集,剩下的作为测试集。
划分成train_X(2500,7),train_Y(2500,7),test_X(166,7),test_X(166,7)四个矩阵。

注意:神经网络的输入需要是一个三维的张量,不能是二维的平面

因此,把其中的训练集输入train_X(2500,7)和test_X(166,7)升维成三维的(2500,1,7)和(166,1,7)。

至此,神经网络的数据处理部分完成了,接下来就是神经网络的搭建参数的设置,还有使用神经网络进行预测

	model = Sequential()
    model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))
    model.add(Dense(7))
    model.add(Dropout(0.25))
    model.compile(loss='mean_squared_error', optimizer='adam')
    model.fit(train_X, train_Y, epochs=50, batch_size=1, validation_data=(test_X, test_Y), verbose=1, shuffle=False)

以上代码是神经网络的搭建和参数的设置部分。
1、设置模型为序贯模型(从头到尾不分叉的线性堆叠模型)。
2、模型设置为LSTM,输入的形式设置为train_X的张量。
3、设置模型的全连接层,输出为7。
4、设置随机失活。
5、设置损失函数和优化器。
6、设置模型参数,包括训练输入、训练输出、神经元数目、优化步长、验证集、模式、不打乱。

以上,模型设置完成,model.fit语句后将自动开始模型的训练,当模型训练完成后,model.save语句会将训练好的模型保存下来,之后再调用模型时,将不再需要从头开始训练,直接使用:

model = load_model("my_model.h5")

加载模型,可以直接跳到下面的预测部分。

模型预测:
将测试集送入模型进行预测,主注意送入模型的数据必须为三维张量,模型输出为二维的数组。
将数组进行逆变换后,用matlab的包展示出来即可。

结论
在这里插入图片描述
单组7个数据,前六个为红球数据,最后为蓝球数据,中间的直线(颜色最深的那一条)为预测数据,由于双色球红球数据为升序排列,实际期并不能预测出任何效果。

其实把数据打乱来预测才是正确的,但没必要了(懒了),能证明LSTM神经网络对于无规律数据是不起作用就行了。

PS:LSTM神经网络对于其他有规律的数据效果是极好的哦,比如轴承正常运转的振动数据、电机正常运转的振动数据等等。

结束语:
其实一开始我已经知道双色球数据是不可能预测出来的,但搞这么多的目标并非真的是为了找出双色球的数据顺序,只是将LSTM神经网络用在其他有规律的数据上时效果好到令我惊讶,甚至一度怀疑我是不是搞错了直接输出结果,所以我借助这个反例来证明我们搭建模型的方法是正确的,从中学习python和神经网络的使用方法、精进自己才是最终目的。(其实我还是有点想借双色球发财的)

小幻月
2021年3月29日

  • 15
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值