LSTM预测股票收盘价

文章目录

  • LSTM模型预测个股收盘价
    • 一、前言
    • 二、LSTM建模
      • 1.模型升级
        • 1.1.升级LSTM
        • 1.2.升级数据集
      • 2.代码解析
        • 2.1.导入相关库
        • 2.2.构建模型
        • 2.4.构建数据
          • 1. 提取数据
          • 2.构建函数
          • 3.数据清洗
          • 4.数据集拆分
        • 2.5.建模
          • 1.训练模型
          • 2.模型评估
          • 3.保存和载入模型

LSTM模型预测个股收盘价

一、前言

本案例来源于知乎:AI For Trading: LSTM模型预测三天后个股收盘价,使用LSTM模型,多个特征指标对个股收盘价进行预测的项目。

二、LSTM建模

LSTM模型是RNN的一种,其特点是在单一循环神经网络的基础上,构建了长短记忆门,也就是在着重于当前数据中存在的信息的同时,还可以发现和记忆存在于数据序列中的长依赖关系。本项目,使用LSTM模型来预测上证指数三天后的收盘价,也就是利用5月10日前的数据,来预测5月15日的收盘价(中间两天是周末)。

1.模型升级

LSTM模型之所有能够具有预测股价的能力,主要的还是模型本身捕捉了价格序列中的时序要素中所包含的信息。对于模型进行预测本身是完全没有问题的,而这次模型升级的根本目标是提升预测精度。关于模型升级主要来自于两方面的,一是通过对模型的优化,二是数据优化。

1.1.升级LSTM

LSTM模型大概有6种变形形式,主要的特点就是针对不同数据输入的类型。这里我选用了Multiple Input模型,也就是多序列输入,单序列输出。选择这个模型,对数据的构建也有非常好的促进作用,可以构建一个张量(多维数组),这个张量是一个5维张量,每个维度是一个特征数据,同时还可以按照N天的方式形成数据切片,这种设计基于两个原因:

  • 数据中包含了大量信息,而越多的特征数据,提供的信息越多,多因子的雏形。
  • 在保持多特征数据的基础上,保留时间序列数据的主要特点。也就是在不增加特征的情况,将特征信息成倍增加。

这种数据处理模式极大的优于诸多传统算法。诸多传统算法还是以单一样本为切片输入所有维度的数据,在捕捉时序中的信息方面是有所欠缺的。

1.2.升级数据集

数据是从大智慧中取出的数据,数据时间段是2010年1月1日—2019年5月10日,数据包含open(开盘价)、close(收盘价)、volume(成交量)、turnover(成交额度)、return(日收益率)。特征选择了5个:4个随处可得的基本特征数据加1个收益率的衍生变量。按照N个交易日的模式,将数据变成一个shape为(M,N,5)的张量表。原数据:上证指数.xlsx

2.代码解析

该项目在JupyterNotebook上执行,其相关代码如下:JupyterNotebook代码

2.1.导入相关库

# 导入所需库

import pandas as pd 
import numpy as np
from numpy import log
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import LSTM, Dense
import keras
from sklearn.metrics import r2_score
import random
import matplotlib.pyplot as plt
# 设置中文、负号正常显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

2.2.构建模型

# 全局参数,所有要调整的参数都在这里
dim = 300  # 输出维度数,也是LSTM的网络节点数
epochs = 300  # 训练代数,可以理解为训练次数
days = 20  # 读取多少天的数据作为一次预测。例如读取20天的历史数据来预测未来1天的情况
batch_size = 535  # 训练批次大小,就是一次性读取多少个样本进行一运算,越大运算速度越快,但是占用内存和显存越大,根据自己的机器性能设置。同时该参数还决定梯度下降算法的下降步长数。

# 开始构建网络
n_steps = days  # 输入张量的维度数
n_features = 5  # 输入张量的维度
model_2 = Sequential()
# 激活函数用relu
model_2.add(LSTM(dim, activation='relu', input_shape=(n_steps, n_features)))
# 输出层使用全连接层,只要一个输出节点
model_2.add(Dense(1))
# 选择优化器和损失函数,优化器为线性规划算法,损失函数使用的是高维空间测定距离函数
model_2.compile(optimizer='rmsprop', loss='mse')

2.4.构建数据

1. 提取数据
  • 其中日收益率计算公式如下:
    r e t u r n = l n ( C l o s e t C l o s e t − 1 ) return=ln(\frac{Close_{t}}{Close_{t-1}}) return=ln(Closet1Closet)
data = pd.read_excel('上证指数.xlsx')
data.head(10)
data.info()

# 提取本项目所使用的数据
data_ = data[['开盘价', '收盘价', '成交量', '成交金额']].loc[(data['日期'] >= '2010-01-01') & (data['日期'] <= '2019-05-10')]
data_['日收益率'] = log(data_[['收盘价']]).diff(-1)
data_.index = data['日期'].loc[(data['日期'] >= '2010-01-01') & (data['日期'] <= '2019-05-10')]
data_.dropna(axis=0, inplace=True)
data_.tail(10)
data_.shape
2.构建函数

构建两个处理数据生成张量表的函数,一个用带标签输出,另一个只处理输入数据集,生成20X5的切片数据。

def processData(data, lb):
    X, Y = [], []
    for i in range(len(data) - lb - 1):
        X.append(data[i:(i + lb), 0])
        try:
            Y.append(data[(i + 2 + lb), 0])
        except:
            Y.append(data[(i + lb), 0])
    return np.array(X), np.array(Y)
    
    
 def pData(data, lb):
    X = []
    for i in range(len(data) - lb - 1):
        X.append(data[i:(i + lb)])
    return np.array(X)
3.数据清洗
close = data_['收盘价']
cl = np.array(close)
cl
cl = cl.reshape(cl.shape[0], 1)
cl
scl = MinMaxScaler()
sc2 = MinMaxScaler()
cl = scl.fit_transform(cl)
cl


# 生成标签
_, y = processData(cl, days)
X = data_.values
X.shape
X = sc2.fit_transform(X)
X
X = pData(X, days)
X.shape
4.数据集拆分
y_train, y_test = y[:int(y.shape[0] * 0.80)], y[int(y.shape[0] * 0.80):]
x_train, x_test = X[:int(X.shape[0] * 0.80)], X[int(X.shape[0] * 0.80):]

2.5.建模

1.训练模型
History = model_2.fit(x_train,y_train,batch_size=batch_size, epochs=epochs,
                      validation_data=(x_test,y_test),shuffle=False)
                      
plt.plot(History.history['loss'], label='loss')
plt.plot(History.history['val_loss'], label='val loss')
plt.legend(loc='best')
plt.title('The loss values of real and predict')
plt.savefig('D:/mojin/self/try/LSTM/result/真实值与预测值的loss值.jpg')
plt.show();

[out]
LSTM预测股票收盘价_第1张图片

2.模型评估
  • 单值预测检验
  • 序列预测检验
  • 预测性能评估
# 随机从测试集中抽取一个单一数据切片进行预测
act =[]
pred = []
i = random.randint(0, x_test.shape[0] - 1)
Xt = model_2.predict(x_test[i].reshape(1, days, 5))
print('预测值:{}, 实际值:{}'.format(Xt, y_test[i].reshape(-1, 1)))
pred.append(Xt)
act.append(y_test[i])
# 将测试集中的所有切片以序列的方式进行预测,查看预测结果与真实值的拟合情况。
y_pred = model_2.predict(x_test)
fig = plt.gcf()
plt.figure(figsize=(8, 4))
plt.plot(y_test.reshape(-1,1),label='y_test')
plt.plot(y_pred,label='Forecast')
plt.title('Predict of test data')
plt.text(100, 0.4, s='测试集R2:%.3f' % (r2_score(y_test.reshape(-1,1), y_pred)))
plt.legend(loc='best')
plt.savefig('D:/mojin/self/try/LSTM/result/测试集的预测效果.jpg')
plt.show();

[out]
LSTM预测股票收盘价_第2张图片

# 描述性统计
a = y_test.reshape(-1,1)
b = Xt
c = a - b #实际值减去预测值
c = pd.DataFrame(c)
c.describe()
3.保存和载入模型
# 保存模型
path = 'D:/mojin/self/try/LSTM/result' # 请自行设置存储路径及文件名,例如:D:\\股票\\my_model
model_2.save(path+'.h5', include_optimizer=True)  # 保存模型本体
model_2.save_weights(path + '_weights.h5')  # 保存模型权重

# 载入模型
path = 'D:/mojin/self/try/LSTM/result'
my_model = keras.models.load_model(path+'.h5')
p_1 = my_model.predict(x_test[1].reshape(1, days, 5))
p_1

p_1 = scl.inverse_transform(p_1)
p_1

你可能感兴趣的:(深度学习)