基于Keras的LSTM多变量时间序列股票预测

朋友多次劝我,用大数据人工智能研究下金融股票,由于本人水平有限,一直没有去想。最近两天,突然想到LSTM是不是很适合做股票预测。通过上网学习,还是真有案例。

适合多输入变量的神经网络模型一直让开发人员很头痛,但基于(LSTM)的循环神经网络能够几乎可以完美的解决多个输入变量的问题。基于(LSTM)的循环神经网络可以很好的利用在时间序列预测上,

长短期记忆循环神经网络等几乎可以完美地模拟多个输入变量的问题,这为时间序列预测带来极大益处。本文介绍了如何在 Keras 深度学习库中搭建用于多变量时间序列预测的 LSTM 模型。

因为市场总是会出现黑天鹅事件,比如股灾,这种不符合规律的事件是很难预测的,本文仅适用学习人工智能技术练习,“当你进入股市后,趋势就变化了”。

Keras是一个高度封装的神经网络框架,提供参数化的API,Keras由纯Python编写而成并基Tensorflow、Theano以及CNTK后端。Keras 为支持快速实验而生,能够把你的idea迅速转换为结果。

关于LSTM

LSTM算法的全称是长短期记忆网络(long short-term memory),由于LSTM算法基于RNN算法改进而来的,一种特殊的RNN网络,规避了标准RNN中梯度爆炸和梯度消失的问题,而且该网络设计出来是为了解决长依赖问题。该网络由 Hochreiter & Schmidhuber (1997)引入,并有许多人对其进行了改进和普及。他们的工作被用来解决了各种各样的问题,直到目前还被广泛应用。

多层LSTM只是将单个cell进行堆叠。LSTM模型为什么比CNN难理解呢?因为它把神经元的数量都藏到cell里面。通过对比CNN,看上面的图是不是有点感觉呢?一个cell其实就是一层神经元,只是LSTM和CNN不同的是,它的每一层t时刻的输出和t-1时刻的状态有关。也就是说当前cell的输出ht不仅仅影响到下一cell(图中右边的那列),还影响本cell下一时刻的状态和输出(图中按时间顺序堆叠的三个绿色的cell)。

理解到这一点了,我们也自然地理解到,xt可以是多维的。然后每个cell的hidden_size都可以进行设置。

数据源来自 这里

LSTM多变量时间序列股票预测

'''
Created on 2020年4月5日

@author: xiaoyw
'''
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential  #Sequential 用于初始化神经网络
from keras.layers import Dense       #Dense 用于添加全连接的神经网络层
from keras.layers import LSTM        #LSTM 用于添加长短期内存层
from keras.layers import Dropout     #Dropout 用于添加防止过拟合的dropout层

#构建训练数据
def train_data():
    dataset_train = pd.read_csv('NSE-TATAGLOBAL.csv')
    training_set = dataset_train.iloc[:, 1:7].values
    dataset_train.head()
        
    sc = MinMaxScaler(feature_range = (0, 1))
    training_set_scaled = sc.fit_transform(training_set)
    
    X_train = []
    y_train = []
    for i in range(60, 2035):
        X_train.append(training_set_scaled[i-60:i, :])
        y_train.append(training_set_scaled[i, :])

    X_train, y_train = np.array(X_train), np.array(y_train)      
    X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 6))
    
    return X_train,y_train,dataset_train,sc
#构建测试数据
def test_data(dataset_train,sc):
    dataset_test = pd.read_csv('tatatest.csv')
    real_stock_price = dataset_test.iloc[:, 1:2].values
    #合并训练集和测试集
    dataset_total = pd.concat((dataset_train, dataset_test), axis = 0)
    db_all = dataset_total.iloc[:, 1:7].values

    inputs = db_all[len(dataset_total) - len(dataset_test) - 60:]
    inputs = inputs.reshape(-1,6)

    inputs = sc.transform(inputs)
    X_test = []
    for i in range(60, 76):
        X_test.append(inputs[i-60:i, :])
        #X_test.append(inputs[i-60:i, 0])
    X_test = np.array(X_test)
    X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 6))
    
    return X_test,real_stock_price
#创建股票预测模型
def stock_model(X_train, y_train):
    regressor = Sequential()
    #LSTM的输入为 [samples, timesteps, features],这里的timesteps为步数,features为维度 这里我们的数据是6维的
    regressor.add(LSTM(units = 50, return_sequences = True, input_shape = (X_train.shape[1], 6)))
    
    regressor.add(Dropout(0.2))
    
    regressor.add(LSTM(units = 50, return_sequences = True))
    regressor.add(Dropout(0.2))
    
    regressor.add(LSTM(units = 50, return_sequences = True))
    regressor.add(Dropout(0.2))
    
    regressor.add(LSTM(units = 50))
    regressor.add(Dropout(0.2))
    #全连接,输出6个
    regressor.add(Dense(units = 6))
    
    regressor.compile(optimizer = 'adam', loss = 'mean_squared_error')
    regressor.fit(X_train, y_train, epochs = 100, batch_size = 32)
    
    return regressor

def main():
    X_train, y_train,dataset_train,sc = train_data()
    
    regressor = stock_model(X_train, y_train)
    X_test,real_stock_price = test_data(dataset_train,sc)
    predicted_stock_price = regressor.predict(X_test)
    
    predicted_stock_price = sc.inverse_transform(predicted_stock_price)
    
    plt.plot(real_stock_price, color = 'black', label = 'TATA Stock Price')
    #显示开盘价
    plt.plot(predicted_stock_price[:,0], color = 'green', label = 'Predicted TATA Stock Price')
    plt.title('TATA Stock Price Prediction')
    plt.xlabel('Time')
    plt.ylabel('TATA Stock Price')
    plt.legend()
    plt.show()

if __name__ == '__main__':
    main()

参考源代码为单变量(开盘价)预测,效果如下左侧图所示,改造成本文代码,为多变量输入并且多维度输出,预测效果(取开盘价)如下右侧图所示。

关于本文技术和代码分析,请关注后续博文。

参考:

《利用Keras长短期记忆(LSTM)模型预测股票价格》 数据人 陆勤 2018.11

《使用Keras进行LSTM实战》 CSDN博客 浅笑古今 2018.09

《学习基于Keras框架的ResNet网络及实践笔记》 CSDN博客 肖永威 2019.06

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章