基于 Keras 的 LSTM 时间序列分析——以苹果股价预测为例

时间:2020-12-15 19:16:38

简介

时间序列简单的说就是各时间点上形成的数值序列,时间序列分析就是通过观察历史数据预测未来的值。预测未来股价走势是一个再好不过的例子了。在本文中,我们将看到如何在递归神经网络的帮助下执行时间序列分析。我们将根据过去5年的股价预测苹果公司之后的股价。

数据集

我们将使用从2013年1月1日到2017年12月31日的苹果股票价格作为训练集,2018年1月的价格作为测试集。所以,为了评估算法的效果,也要下载2018年1月的实际股票价格。

打开包含五年数据的苹果股票价格的训练文件后可以看到如下几列:“Date,Open,High,Low,Close,Adj Close,Volume”。本文,我们只关注日期和开盘价格,也即“Date”和“Open”两列。

我们先把日期和开盘价直观表示出来:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('./AAPL_train.csv')

x, y = pd.to_datetime(df['Date']), df['Open']

plt.title('AAPL Opening Stock Prices Against The Date')
plt.plot(x, y)

plt.show()

结果如下:

基于 Keras 的 LSTM 时间序列分析——以苹果股价预测为例

从图中可以看出,这种趋势是高度非线性的,我们很难用这些信息来总结趋势规律。这时候 LSTM 就可以派上用场了。LSTM(Long Short-Term Memory Network,长短期记忆网络)是一种能够记忆过去信息的递归神经网络,在预测未来值的同时,将过去的信息考虑在内。

现在让我们看看 LSTM 是如何用于时间序列分析的。

预测未来股价

股票价格预测与其他机器学习问题一样,都是先其中给定一组特征,然后再去预测相应的值。下面是执行步骤:

导入库

首先导入所需的库:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout

导入数据集

读取数据集并且只保留开盘价数据:

apple_training_complete = pd.read_csv('./AAPL_train.csv')
apple_training_processed = apple_training_complete.iloc[:, 1:2].values

数据归一化

这里将使用 sklear.preprocessing 中的 MinMaxScaler 类进行数据归一化,其中参数 feature_range 是用来指定缩放数据的范围:

scaler = MinMaxScaler(feature_range=(0, 1))

apple_training_scaled = scaler.fit_transform(apple_training_processed)

转换训练数据

如前文所提,在一个时间序列问题中,我们要根据天数 T-N 的数据去预测时间T的值,其中N可以是任意数。这里我们将根据过去60天的股票开盘价数据去预测股票开盘价。当然,你可以将60改成别的数字去看看运行效果,反正我这里是60是最好的选择。

下面我们将前60天的数据作为特征集,第61天的数据作为标签。创建特征和标签集:

features_set = []
labels = []
for i in range(60, 1260):
    features_set.append(apple_training_scaled[i - 60:i, 0])
    labels.append(apple_training_scaled[i, 0])

将特征集和标签集转换为 numpy 数组:

features_set, labels = np.array(features_set), np.array(labels)
features_set = np.reshape(features_set, (features_set.shape[0], features_set.shape[1], 1))

训练

创建四个 LSTM 层 与一个全连接层的训练模型,编译后开始训练。

model = Sequential()

model.add(LSTM(units=50, return_sequences=True, input_shape=(features_set.shape[1], 1)))
model.add(Dropout(0.2))

model.add(LSTM(units=50, return_sequences=True))
model.add(Dropout(0.2))

model.add(LSTM(units=50, return_sequences=True))
model.add(Dropout(0.2))

model.add(LSTM(units=50))
model.add(Dropout(0.2))

model.add(Dense(units=1))

model.compile(optimizer='adam', loss='mean_squared_error')

model.fit(features_set, labels, epochs=100, batch_size=32)

训练要花上一些时间,当然电脑好的话就不用愁了,反正我是等了很久。

测试

apple_testing_complete = pd.read_csv('./AAPL_test.csv')
apple_testing_processed = apple_testing_complete.iloc[:, 1:2].values

apple_total = pd.concat((apple_training_complete['Open'], apple_testing_complete['Open']), axis=0)

test_inputs = apple_total[len(apple_total) - len(apple_testing_complete) - 60:].values
test_inputs = test_inputs.reshape(-1, 1)
test_inputs = scaler.transform(test_inputs)

test_features = []
for i in range(60, 80):
    test_features.append(test_inputs[i - 60:i, 0])

test_features = np.array(test_features)
test_features = np.reshape(test_features, (test_features.shape[0], test_features.shape[1], 1))

predictions = model.predict(test_features)
predictions = scaler.inverse_transform(predictions)

plt.figure(figsize=(10, 6))
plt.plot(apple_testing_processed, color='blue', label='Actual Apple Stock Price')
plt.plot(predictions, color='red', label='Predicted Apple Stock Price')
plt.title('Apple Stock Price Prediction')
plt.xlabel('Date')
plt.ylabel('Apple Stock Price')
plt.legend()
plt.show()

预测结果:

基于 Keras 的 LSTM 时间序列分析——以苹果股价预测为例

图中蓝线2018年1月1日至今的实际股价,而红线表示预测的股价。很明显,该预测方法还是挺准的。如果对其他公司感兴趣的当然也可以去下载其他公司的数据根据本文给出的方法进行测试。欢迎关注呀~