前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于RNN和LSTM的股市预测方法

基于RNN和LSTM的股市预测方法

作者头像
量化投资与机器学习微信公众号
发布2019-02-26 16:27:46
2.9K0
发布2019-02-26 16:27:46
举报

本期作者:Aniruddha Choudhury

本期编辑:1+1=6

前言

对许多研究人员和分析师来说,预测股价的艺术一直是一项艰巨的任务。事实上,投资者对股票价格预测的研究领域非常感兴趣。许多投资者都渴望知道股票市场的未来情况。良好和有效的股票市场预测系统通过提供股票市场未来走向等支持性信息,帮助交易员、投资者和分析师。本文提出了一种基于RNN和LSTM的股票市场指数预测方法。

介绍

金融指标复杂,股市波动剧烈。然而,随着科技的进步,从股票市场获得稳定财富的机会增加了,这也帮助专家们找到最有信息的指标,做出更好的预测。市场价值的预测对于实现股票期权购买的利润最大化和保持低风险具有重要意义。RNN已被证明是处理序列数据的最强大的模型之一。LSTM是最成功的RNNs架构之一。LSTM引入了记忆单元,它是一种计算单元,取代了网络隐含层中的传统人工神经元。利用这些记忆单元,网络能够有效地将记忆关联起来,并能及时远程输入,从而适应随时间动态掌握数据结构,具有较高的预测能力。

LSTM

我们将从单个时间步骤实现LSTM单元。然后我们可以在for循环中迭代调用它,让它使用Tx time-steps处理输入。

方法

第一阶段:原始数据。

在这个阶段,基于谷歌的历史数据用于预测未来价格。

代码语言:javascript
复制
dataset = pd.read_csv('Google_Stock_Price_Train.csv',index_col="Date",parse_dates=True)

第二阶段:预处理数据

1、数据离散化

2、数据标准化

3、数据缺失值处理

4、将数据集分为训练集和测试集。

代码语言:javascript
复制
#Data cleaning
dataset.isna().any()
# Feature Scaling Normalization
from sklearn.preprocessing import MinMaxScaler
sc = MinMaxScaler(feature_range = (0, 1))
training_set_scaled = sc.fit_transform(training_set)
# Creating a data structure with 60 timesteps and 1 output
X_train = []
y_train = []
for i in range(60, 1258):
    X_train.append(training_set_scaled[i-60:i, 0])
    y_train.append(training_set_scaled[i, 0])
X_train, y_train = np.array(X_train), np.array(y_train)

# Reshaping
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))

第三阶段:在这一层中,只选择需要输入神经网络的特征。我们将从日期、开、高、低、收和成交量中选择特征。

代码语言:javascript
复制
Building the RNN LSTM model
# Importing the Keras libraries and packages
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout
Using TensorFlow backend.

训练神经网络:在这一阶段,将数据输入神经网络进行随机偏差和权值的预测训练。

代码语言:javascript
复制
# Initialising the RNN
regressor = Sequential()
# Adding the first LSTM layer and some Dropout regularisation
regressor.add(LSTM(units = 50, return_sequences = True, input_shape = (X_train.shape[1], 1)))regressor.add(Dropout(0.2))

# Adding a second LSTM layer and some Dropout regularisation
regressor.add(LSTM(units = 50, return_sequences = True))
regressor.add(Dropout(0.2))

# Adding a third LSTM layer and some Dropout regularisation
regressor.add(LSTM(units = 50, return_sequences = True))
regressor.add(Dropout(0.2))

# Adding a fourth LSTM layer and some Dropout regularisation
regressor.add(LSTM(units = 50))
regressor.add(Dropout(0.2))

# Adding the output layer
regressor.add(Dense(units = 1))
# Compiling the RNN
regressor.compile(optimizer = 'adam', loss = 'mean_squared_error')

# Fitting the RNN to the Training set
regressor.fit(X_train, y_train, epochs = 100, batch_size = 32)

优化器

使用的优化器类型会极大地影响算法收敛到最小值的速度。此外,重要的是要有一些随机性的概念,以避免陷入局部最小值而无法达到全局最小值。有一些很好的算法,但我们选择使用Adam优化器。Adam优化器结合了其他两个优化器的优点:ADAgrad和RMSprop。

ADAgrad优化器实际上为每个参数和每个时间步骤使用不同的学习率。ADAgrad背后的原因是,不频繁的参数必须有较大的学习率,而频繁的参数必须有较小的学习率。也就是说,ADAgrad的随机梯度下降更新变成

学习率是根据每个参数计算过去的梯度来计算的。因此:

其中G是过去梯度平方和的矩阵。这种优化的问题是,随着迭代次数的增加,学习速率开始迅速消失。

RMSprop只考虑使用一定数量的前一个梯度来修正学习速率递减的问题。的更新成为:

现在我们已经了解了这两个优化器是如何工作的,接下来我们可以看看Adam是如何工作的。

自适应矩估计,或Adam,是另一种计算每个参数的自适应学习速率的方法,它考虑了过去的平方梯度的指数衰减平均值和过去梯度的指数衰减平均值。这可以表示为:

v和m可以分别作为梯度的一阶矩和二阶矩的估计值,从而得到自适应矩估计的名称。当这一理论首次被使用时,研究人员观察到一种固有的对0的偏见,他们用以下的估计来反驳这种偏见:

这就引出了最终的渐变更新规则:

其优点总结如下:

1、对于每个参数和每个迭代,学习率是不同的。

2、学习不会像ADAgrad那样减少。

3、梯度更新使用了权重分布的矩值。

正则化

训练模型的另一个重要方面是确保权重不要太大,并开始关注于一个数据点,因此会过度拟合。因此,包括对大权重的惩罚(大的定义将取决于所使用的正则化器的类型)。选择使用Tikhonov正则化,它可以被认为是如下最小化问题:

函数空间位于可复制的核希尔伯特空间(RKHS)这一事实确保了范数的概念的存在。这允许我们将规范的概念编码到我们的正则化器中。

Dropouts

一种防止过拟合的新方法考虑了当一些神经元突然停止工作时会发生什么。这就迫使模型不要过度依赖任何一组神经元,并考虑到所有的神经元。Dropout发现它们的作用是使神经元更加强健,从而使他们能够在不关注任何一个神经元的情况下预测这一趋势。这里是使用Dropout的结果:

Output Generation:在该层中,将RNN输出层生成的输出值与目标值进行比较。利用反向传播算法调整网络的权值和偏差,使目标与输出值之间的误差或差降至最小。

代码语言:javascript
复制
Epoch 97/100
1198/1198 [==============================] - 6s 5ms/step - loss: 0.0018
Epoch 98/100
1198/1198 [==============================] - 6s 5ms/step - loss: 0.0014
Epoch 99/100
1198/1198 [==============================] - 6s 5ms/step - loss: 0.0014
Epoch 100/100
1198/1198 [==============================] - 6s 5ms/step - loss: 0.0015

我们对测试数据的预处理也采用了同样的方法:

代码语言:javascript
复制
# Getting the real stock price of 2017
dataset_test = pd.read_csv('Google_Stock_Price_Test.csv',index_col="Date",parse_dates=True)
# Getting the predicted stock price
dataset_total = pd.concat((dataset['Open'], dataset_test['Open']), axis = 0)
inputs = dataset_total[len(dataset_total) - len(dataset_test) - 60:].values
inputs = inputs.reshape(-1,1)
inputs = sc.transform(inputs)
X_test = []
for i in range(60, 80):
    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], 1))
predicted_stock_price = regressor.predict(X_test)
predicted_stock_price = sc.inverse_transform(predicted_stock_price)

可视化

基于keras API函数,上述所有分析都可以相对容易地实现。

代码语言:javascript
复制
# Visualising the results
plt.plot(real_stock_price, color = 'red', label = 'Real Google Stock Price')
plt.plot(predicted_stock_price, color = 'blue', label = 'Predicted Google Stock Price')
plt.title('Google Stock Price Prediction')
plt.xlabel('Time')
plt.ylabel('Google Stock Price')
plt.legend()
plt.show()

时间序列上的移动平均值

时间序列模型的滚动分析常用于评估模型随时间的稳定性。当使用统计模型分析金融时间序列数据时,一个关键的假设是模型的参数随时间的变化是恒定的。

代码语言:javascript
复制
dataset['Close: 30 Day Mean'] = dataset['Close'].rolling(window=30).mean()
dataset[['Close','Close: 30 Day Mean']].plot(figsize=(16,6))

股票在一段时间内的开盘表现。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 量化投资与机器学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档