900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 基于LSTM的哔哩哔哩股票预测·超详细教程

基于LSTM的哔哩哔哩股票预测·超详细教程

时间:2020-06-09 22:18:00

相关推荐

基于LSTM的哔哩哔哩股票预测·超详细教程

图片来源:/read/cv328714/

文章内容分为以下8个部分

1 问题描述2 模块准备3 数据准备 3.1 获取数据3.2 缺失值处理3.3 拆分训练集与测试集3.4 数据归一化3.5 重构数据4. 模型建立5. 模型拟合6. 模型预测7. 预测结果可视化8. 本文的缺陷

本视频也有对应的视频(6min):

/video/BV1dk4y117nz

本教程的完整代码:

/kisaragiRY/Bilibili-Stock-Prediction

并且作为补充,想了解LSTM具体原理的同学可以看一下colah的博文:

英文原版:

http://colah.github.io/posts/-08-Understanding-LSTMs/

中文翻译版:

/p/95d5c461924c

让我们正式开始吧!

1 问题描述

在这篇文章中,我们将应用一个叫Long short-term memory (LSTM)的循环神经网络(Recurrent Neural Network, RNN),对bilibili(NASDAQ: BILI)从上市-3-28-8-18的股票数据进行分析及预测,并详细介绍其Python代码的实现。

想要预测精确的股票价格是不可能的,神经网络算法仅能帮助探索一下股票的大致走势,所以

注意!!:此篇文章内容不建议用于股票投资决策使用,所有结果仅作为参考!!

2 模块准备

如果没有某个模块,如pandas_datareader,可以在命令窗口输入以下代码来下载

pip install pandas_datareader

几乎所有Python的模块或包的下载方式都是这样

pip install [模块的名字]

接下来引入本篇文章要用上的所有模块

#引入相关模块#读取数据用的模块from pandas_datareader import data as pdr#数据预处理用的模块import mathfrom sklearn.preprocessing import MinMaxScalerimport numpy as np#建立模型用的模块from keras.models import Sequentialfrom keras.layers import Dense, Dropout, LSTM, TimeDistributed#作图用的模块import missingno as msnoimport matplotlib.pyplot as pltimport seaborn as snssns.set(color_codes='Ture')

3 数据准备

3.1 获取数据

#根据股票代码BILI,从雅虎财经上获取从-3-28到-8-18的股票数据df=pdr.get_data_yahoo('BILI',start='-03-28',end='-08-18')#查看数据df

输出:

数据有603行,6列。即样本量(samples)是603,特征数(features)是6,分别是当日最高价(High),最低价(Low),开盘价(Open),收盘价(Close),成交量(Volume),调整后的收盘价(Adj Close)。

本篇文章只对收盘价这一列数据进行拟合及预测。

3.2 缺失值处理

接下来我们要查看一下缺失值,若存在缺失值,我们则需要做一些相应处理,根据情况看是删除还是填充

#可视化缺失值msno.matrix(df)

输出:

由上图可以看出,此数据是完整数据,没有缺失值,可以继续接下来的步骤

3.3 拆分训练集与测试集

我们将取前80%的数据作为训练集来训练模型,后20%的数据作为测试集来测试模型的预测能力

#将dataframe按索引降序排列data = df.sort_index(ascending=True, axis=0)#只用Close这一列,即只使用股票的收盘价来进行拟合和预测dataset=data[['Close']].values#取80%的数据作为训练集training_data_len=math.ceil(len(dataset)*.8)train_data=dataset[0:training_data_len,:]#取剩下的数据作为测试集#在做预测时,余下的数据的第一个数据,需要前60天的数据来预测,因此这倒溯了60天test_data = dataset[training_data_len-60: , : ]

3.4 数据归一化

这一步,会将数据映射到[0,1]区间,目的是为了提升模型的收敛速度,提升模型的精度。

这里采用的方法叫min-max标准化(Min-max normalization)或0-1标准化(0-1 normalization)

xnorm=x−min(x)max(x)−min(x)x_{norm}=\frac{x-min(x)}{max(x)-min(x)} xnorm​=max(x)−min(x)x−min(x)​

#特征缩放scaler=MinMaxScaler(feature_range=(0,1))scaled_train=scaler.fit_transform(train_data)scaled_test=scaler.fit_transform(test_data)

3.5 重构数据

这一节的目的是使数据能符合算法的输入要求,分为三步

将数据集拆分成x和y两部分,用x来预测y,将数据转变成时间序列和有监督学习问题

为了图像说明简便,假如我们以3天为一个timestep,即用前3天的数据(橙色大框,绿色大框,x)来预测第4天的数据(橙色小框,绿色小框,y)。在此博客中,实际的timesteps取的是60,即用前60天数据预测第61天数据。 将list类型数据转变成array数据,以便第三步使用将二维数据转成三维数据。LSTM的输入需要一个三维数组(samples, timesteps, feature)分别指样本量,时间步数,特征数目。

x_train和x_test会作为LSTM的输入数据,而此时它俩是二维数据(samples, timsteps=60),我们需要给这俩数据再添一维feature,因为我们只取了收盘价来分析,所以此处的feature=1。

#训练集的重构#1 分离x和yx_train=[]y_train=[]for i in range(60,len(scaled_train)):x_train.append(scaled_train[i-60:i,0])y_train.append(scaled_train[i,0])#2 将list类型数据转变成array数据x_train,y_train=np.array(x_train),np.array(y_train)#3 将二维数据变成三维数据x_train=np.reshape(x_train,(x_train.shape[0],x_train.shape[1],1))#测试集的重构#1 分离x和yx_test = []y_test = dataset[training_data_len: , : ] for i in range(60,len(scaled_test)):x_test.append(scaled_test[i-60:i,0])#2 将list类型数据转变成array数据x_test = np.array(x_test)#3 将二维数据变成三维数据x_test = np.reshape(x_test, (x_test.shape[0],x_test.shape[1],1))

4. 模型建立

初始化神经网络:Sequential()

LSTM层:LSTM()

一般两层LSTM就能比较好的拟合数据了,多层的LSTM会提升模型的拟合度,但同时也增加了模型的复杂度和训练的难度,有兴趣的读者也可以试试多层LSTM效果。

参数units=50的意思是该层有50个LSTM神经元,并且这一层输出的是一个50维的向量

参数input_shape需要我们输入一个二维数组,包含timesteps和features,即时间步数和特征数目

参数return_sequences是用来设定是否返回含有timesteps这一维的数组

True返回的是一个三维数组(batch size,timesteps,number of units),分别指批数目,时间步数,神经元数目,False返回的是一个二维数组(batch size, number of units)

防止过拟合的dropout层:Dropout()

函数Dropout(0.2)意思是上一层输出的数据中,随机删除20%的数据

全连接的神经网络层:Dense()

也叫Densely connected layer,意思是这一层的每个节点与上一层的所有节点相连,参数unites=1的意思是这一层有一个神经元。

神经网络编译:compile()

用Adam来优化,以MSE(均方误差)为损失函数

#构建模型#初始化模型model = Sequential()#LSTM层model.add(LSTM(units=50, return_sequences=True,input_shape=(x_train.shape[1],1)))#Dropout层model.add(Dropout(.2))#LSTM层model.add(LSTM(units=50, return_sequences=False))#Dropout层model.add(Dropout(.2))#全连接层model.add(Dense(units=1))#模型编译pile(optimizer='adam', loss='mean_squared_error')

整体神经网络的结构如图

#模型结构model.summary()

输出:(能看到每层输出的数据结构以及参数个数)

5. 模型拟合

用训练集数据x_train,y_train来训练上一步建立好的模型,本文不涉及调整参数的步骤,在这笔者只是对参数batch_sizeepochs随机给了两个值25和10

batch_size:将完整的数据分为多次输入,一次输入的样本大小叫做batch_sizeepochs:完整的数据通过一次神经网络,称为一次epoch

而其实这两个值对模型拟合的好坏影响很大,笔者会在以后的文章中再仔细探讨一下如何调整参数。

#拟合模型model.fit(x_train, y_train, batch_size=25, epochs=10)

6. 模型预测

用训练集训练好模型后,用测试集来做预测;

又因之前对x_test做过归一化处理,这里需要用inverse_transform()这个函数来将它复原

#预测predictions = model.predict(x_test) #还原 特征缩放predictions = scaler.inverse_transform(predictions)

7. 预测结果可视化

#创建用来画图的dataframetrain = data[:training_data_len]valid = data[training_data_len:]#给valid添加新的一列,把预测值predictions赋值给新的一列valid['Predictions'] = predictions#开始作图#图像大小plt.figure(figsize=(16,8))#图像标题plt.title('Model')#x轴plt.xlabel('Date', fontsize=18)#y轴plt.ylabel('Close Price USD ($)', fontsize=18)#画训练集的折线图plt.plot(train['Close'])#分别画出真实值和预测值的折线图plt.plot(valid[['Close', 'Predictions']])#展示图例plt.legend(['Train', 'Val', 'Predictions'], loc='lower right')plt.show()

输出:

由图可以看出算法LSTM的确能较为精确的预测出股票的浮动趋势

8. 本文的缺陷

本文只用了一种办法LSTM来做预测,其实还有很多别的方法,如传统的ARIMA,还有机器学习的办法比如k近邻等等本文未涉及参数调整。参数调整的方法有很多,除了手动调参,还可以借用一些算法比如网格搜索(Grid Search),随机网格搜索(Random Search),以及贝叶斯的办法。 神经网络结构里的参数,比如unites(神经元数目);拟合模型时batch size和epochs这两个参数只是随便给了两个值。 …(如果你发现更多的不足,请一定私信或在评论区留言~~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。