本文探索Python中的长短期记忆(LSTM)网络,以及如何使用它们来进行股市预测。
在本文中,你将看到如何使用一个被称为长短时记忆的时间序列模型。LSTM模型很强大,特别是在保留长期记忆方面。在本文中,你将解决以下主题。
- 理解为什么你需要能够预测股票价格的变动。
- 下载数据 - 使用从雅虎财经收集的股市数据
- 分割训练-测试数据,并进行数据归一化
- 应用单步预测技术。
- 讨论LSTM模型。
- 用当前的数据预测和可视化未来的股票市场
为什么你需要时间序列模型?
你希望对股票价格进行正确的建模,所以作为一个股票买家,你可以合理地决定何时买入股票,何时卖出股票以获得利润。这就是时间序列模型的作用。你需要好的机器学习模型,它可以观察一连串数据的历史,并正确预测该序列的未来数据。
提示:股票市场的价格是高度不可预测和波动的。这意味着数据中没有一致的模式,使你能够近乎完美地模拟股票价格随时间变化。
然而,我们不要一味地认为这只是一个随机的或者随机的过程,机器学习没有希望。我们至少对数据进行建模,做出的预测与数据的实际行为相关。换句话说,你不需要未来确切的股票价值,而是需要股票价格的变动(也就是说,如果它在不久的将来会上涨或下跌)。
# 可用的库
import numpy as np
import tensorflow as tf
下载数据
股票价格有几种不同的变量。它们是
- 开盘:当天的开盘股票价格
- 收盘价:当天的收盘股价
- 高点:数据中最高的股票价格
- 低点:当天的最低股价
获取数据
你要利用航空公司的股票市场价格来进行预测,所以你把股票代码设置为 "AAL"。此外,你还定义了一个url\_string,它将返回一个JSON文件,其中包含航空公司过去20年的所有股市数据,以及一个file\_to_save,它是你保存数据的文件。
接下来,指定条件:如果你还没有保存数据,从你在url\_string中设置的URL中抓取数据;把日期、低点、高点、成交量、收盘价、开盘价存储到一个pandas DataFrame df中,把它保存到file\_to_save。
# 从URL中抓取数据 # 将日期、低点、高点、成交量、收盘价、开盘价存储到Pandas DataFrame中 #提取股票市场数据 df = pd.DataFrame(columns=\['Date', 'Low', 'High', 'Close', ' Open'\]) print('数据保存到:%s'%file\_to\_save) # 如果数据已经存在,只需从CSV中加载即可 否则。 print('文件已经存在,从CSV中加载数据') df = pd.read\_csv(file\_to_save)
数据探索
在这里你将把收集的数据输出到DataFrame中。你还应该确保数据是按日期排序的,因为数据的顺序在时间序列建模中至关重要。
# 按日期对数据框架进行排序 df = df.sort_values('Date') # 仔细检查结果 df.head()
数据可视化
现在让我们来看看是什么样的数据。
plot(range(df.shape\[0\]),(df)/2.0)
这张图已经说明了很多问题。我选择这家公司而不是其他公司的原因是,这张图随着时间的推移,股票价格有不同表现行为。这将使模型学习更加稳健,并且给你一个价格变化来测试对各种情况的预测有多好。
另一个需要注意的是,接近2017年的数值要比接近20世纪70年代的数值高得多,而且波动也大。因此,你需要确保数据在整个时间范围内表现为类似的价格范围,需要将数据标准化。
点击标题查阅相关内容
R语言Keras用RNN、双向RNNs递归神经网络、LSTM分析预测温度时间序列、 IMDB电影评分情感
左右滑动查看更多
01
02
03
04
将数据分割成训练集和测试集
你将使用通过取一天中最高和最低价格的平均值计算出的中间价格。
现在你可以把训练数据和测试数据分开。训练数据将是时间序列的前4000个数据点,其余的将是测试数据。
train_data = mid\[:4000\] test_data = mid\[4000:\]
标准化数据
现在你需要定义标准化来规范数据。将训练和测试数据变化为[data\_size, num\_features]的维度。
将测试数据和训练数据相对于训练数据归一。
scaler = MinMaxScaler()
由于你先前的观察,即不同时间段的数据有不同的值范围,通过将全序列分割成窗口来标准化数据。如果你不这样做,早期的数据将接近于0,对学习过程不会有太大的价值。这里你选择了一个800的窗口大小。
提示:在选择窗口大小时,不要太小,因为当你进行窗口标准化时,会在每个窗口的最末端引入一个断点,因为每个窗口都是独立标准化的。
# 用训练数据和平滑数据训练 window_size = 800 scaler.transform(train\_data\[di:di+window\_size,:\]) 将数据重塑为[data_size]的形状。 # 重塑训练和测试数据 reshape(-1) # 对测试数据进行标准化处理 scaler.transform(test_data).reshape(-1)
现在你可以使用指数移动平均线对数据进行平滑处理。
请注意,你应该只平滑训练数据。
# 现在进行指数移动平均平滑处理 # 所以数据会比原来的锯齿状数据有一个更平滑的曲线 EMA = gamma\*train\[i\] + (1-gamma)\*EMA train\[i\] = EMA
通过平均法进行单步超前预测
平均法允许你通过将未来的股票价格表示为以前观察到的股票价格的平均值来进行预测(通常是提前一个时间步)。下面看两种平均技术;标准平均法和指数移动平均法。你将对这两种算法产生的结果进行定性(目测)和定量(平均平方误差)的评估。
平均平方误差(MSE)的计算方法是:取前一步的真实值和预测值之间的平方误差,并对所有的预测值进行平均。
标准平均
可以通过首先尝试将其作为一个平均计算问题的模型来理解这个问题的难度。首先,尝试预测未来的股票市场价格(例如,xt+1),作为一个固定大小的窗口(例如,xt-N,...,xt)(例如之前的100天)内先前观察到的股票市场价格的平均值。此后,尝试更高级的 "指数移动平均 "方法,看看它的效果如何。然后,进入长短期记忆模型
首先,正常的平均数。
换句话说,你说t+1的预测是你在t到t-N的窗口内观察到的所有股票价格的平均值。
pred.append(np.mean(train\[idx-window_size:idx\])) mse\_errors.append((std\_avg\[-1\]-train\[pred_idx\])**2) MSE: 0.00418
看一下下面的平均结果。它与股票的实际行为相当接近。接下来,你将看到一个更准确的一步预测方法。
plt.plot(std\_avg\_pred) plt.legend(fontsize=18) plt.show()
那么,上面的图表(和MSE)说明了什么?
似乎对于非常短的预测(提前一天)来说,这个模型还不算太差。鉴于股票价格不会在一夜之间从0变化到100,这种行为是合理的。接下来,使用指数移动平均线。
指数移动平均线
你可能已经在互联网上看到一些文章,使用非常复杂的模型,并预测了几乎准确的股票市场行为。但是请注意! 这些只是视觉上的错觉,并不是由于学到了有用的东西。你将在下面看到如何用一个简单的平均法来复制这种行为。
在指数移动平均法中,你计算xt+1为。
其中 和 是在一段时间内保持的指数移动平均数值。.
上述公式基本上是计算t+1时间步长的指数移动平均线,并将其作为超前一步的预测。γ决定最近的预测对EMA的贡献是什么。例如,γ=0.1只能得到当前值的10%进入EMA。因为你只取最近的一小部分,它允许保留你在平均数中很早看到的更早的值。请看下面用于预测向前一步的情况。
for idx in range(1,N): mean = mean\*dec + (1.0-de)\*train\[idx-1\] pred.append(mean) MSE: 0.00003 plt.plot(mid_data) plt.plot(pred)