RNN实现股票时间序列预测(Tensorflow版本)

前言

时序问题是数据挖掘过程中常见的一个业务场景,机器学习模型中也有像ARIMA,SARIMA等等优秀的模型,同样很多神经网络模型也可以有效解决时序问题,本次就用RNN神经网络对分析股票成交量的走势。

股票数据集下载:https://pan.baidu.com/s/1S5Dsq2oH_1T7IKSoDdh6Jg
提取码:DJNB

数据可视化

首先导入本次需要用到的所有可能用到的库

from tensorflow.keras import layers
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
from sklearn.preprocessing import MinMaxScaler
import statsmodels.api as sm
import matplotlib.dates as dates
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import math
from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout, LSTM
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from keras import optimizers
import time

读入数据集,对数据集进行归一化处理,然后将数据集划分为训练集和测试集:

#数据读取和预处理
train=pd.read_csv('股票数据.csv',usecols=[0, 5],parse_dates=[0],index_col=0)
#对数据集进行可视化
plt.figure(figsize=(20, 10))
plt.plot(train['volume'],color='r')
plt.ylabel('volume')
plt.xlabel('date')
plt.show()
train = train.values
scaler = MinMaxScaler(feature_range=(0, 1))
train = scaler.fit_transform(train.reshape(-1, 1))
#划分训练集和测试集
train_size = int(len(train)*0.8)
test_size = len(train)-train_size
test=train[train_size: len(train)]
train=train[0: train_size]

数据集整体分布如下图:
在这里插入图片描述

数据集构建

然后是进行输入数据集的构建,RNN模型的输入是矩阵格式,而且数据是三个维度的,因为RNN和LSTM都是循环神经网络,循环神经网络的输出数据会作为输入数据再次输入网络中,所有对应在时间维度具有高依赖性的数据我们采用RNN的效果非常好,神经网络可以提取出数据在时间维度上的特征。这里的time_back就是需要前面几个数据来对后面的数据进行预测,可以自行改变time_back的值,也会有差异。

#数据集构建
def dataset_to_array(dataset, time_back):
    dataX=[]
    dataY=[]
    for i in range(len(dataset)-time_back-1):
        a = dataset[i: (i+time_back)]
        dataX.append(a)
        dataY.append(dataset[i+time_back])
    return np.array(dataX), np.array(dataY)
time_back = 1
trainX, trainY = dataset_to_array(train, time_back)
testX, testY = dataset_to_array(test, time_back)

模型构建及训练

这里我就简单地构建了一个RNN模型,因为数据集比较小,而且数据简单。模型构建方面可以自行改变了有很多,可以加隐藏层,可以控制神经元个数,也可以为防止过拟合做一些调整,优化器激活函数都可以自行改变,效果可能都会有差异。

#RNN模型构建
np.random.seed(2017)
model=tf.keras.models.Sequential([
    tf.keras.layers.SimpleRNN(input_dim=1, units=50, return_sequences=True),
    tf.keras.layers.SimpleRNN(units=128),
    tf.keras.layers.Dense(units=64,activation='sigmoid'),
    tf.keras.layers.Dense(units=1,activation='sigmoid')
])
model.compile(optimizer=keras.optimizers.Adam(0.01),loss=keras.losses.mean_squared_error)
model_information=model.fit(trainX,trainY,epochs=100,verbose=1)
information_loss=model_information.history['loss']  #模型训练损失
#模型损失可视化
def loss(information_loss):
    plt.figure(figsize=(12, 8))
    plt.plot(information_loss)
    plt.title('model loss')
    plt.ylabel('loss')
    plt.xlabel('epoch')
    plt.show()
loss(information_loss)

模型训练好后就对模型的损失进行一个可视化,可以看到模型还是收敛的,损失最终趋于稳定:
在这里插入图片描述

模型预测

模型训练好后就对测试集进行预测,然后将模型对测试集的预测结果和测试集的真实值进行一个可视化对比。

#对测试集进行预测
testPredict = model.predict(testX)
testPredict = scaler.inverse_transform(testPredict)
testY = scaler.inverse_transform(testY)
testScore = math.sqrt(mean_squared_error(testY, testPredict[:, 0]))
print('测试集的RMSE分数 %.2f' %(testScore))
#测试集进行可视化
plt.figure(figsize=(15, 5))
#plt.plot(range(len(testPredict)-1), testPredict[1:], label='prediction', lineWidth=1)
plt.plot(range(len(testPredict)), testPredict, label='prediction', lineWidth=1)
plt.plot(range(len(testY)), testY, label='true', lineWidth=1)
plt.ylabel('volume')
plt.xlabel('date')
plt.legend()
plt.title("prediction and true")
plt.show()

在模型进行可视化的时候出现了一个非常有趣的问题,可以看到下图有一个明显的滞后问题,测试集的预测结果总是比真实值慢了一步,这里的问题在于我们在构建数据集的时候是选择前一次的数据作为后一次数据的预测,所以模型在预测的时候就是将前一次的值加上损失之后就作为预测值了(这是我的愚见,如果有错误请指正)。所以其实这个模型是没啥实际用的,也没学到太多的东西,一方面数据量也不大,一方面时间也比较短,不太具有说服力。
在这里插入图片描述
如果想看着更加准确一点,就需要将测试集时间提前一天,用上面我注释的代码即可效果如下图:
在这里插入图片描述
源码也可以通过以下地址获取:https://github.com/CquptDJ/CquptDJ/tree/main

写在最后

关于RNN滞后问题,如果有更懂的大佬能做出更好的解释欢迎评论,我也会查阅更多资料。本人才疏学浅,如果有错误或者理解不到位的地方请指正!

  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值