博客
【求职分享】
【笔试/面试】
一文读懂:深度学习网络预测股票!
Feb 03,2023
分享本文:
大家好, 我是Lucy@FinTech社区。股票数据数量繁多,实时动态变化,也无简单的规律可循。所以想要预测股票,可不是一件容易的事情。你知道如何用深度学习网络来预测变幻莫测的股票吗?这篇文章将给你答案!
欢迎大家加入FinTech社区,攒人脉,提认知,求职招聘!
要预测股票,可不是一件容易的事情,这是因为股票数据数量繁多,实时动态变化,也无简单的规律可循。要模拟该类动态数据,则需要运用有效的模拟技术,能够快速得分析出隐藏的关联模式,及动态变化规律。
深度学习中的神经网络,具有强大的自学习功能,能够从现存的数据中快速发现作用规律及变化模式,并运用规律和模式预测股票。
然而纵观全网,并没有一篇文章用科学的方法详解如何用神经网络有效的预测股票,这是因为:
-
缺乏有效的数据;
-
实战中有多种网路学习模型,不知如何选择;
-
没有一个系统性的项目框架,来进行实例演示;
看完这篇文章,你将收获:
-
如何用一个现在流行且可用的预测模型进行股票预测;
-
用神经网络进行股票预测的实例化流程;
-
用神经网络进行股票预测的实例化结论和有待改进的地方。
一、数据及模型选择
我们的目的是用实例简洁说明如何用神经网络模型预测股票走向,因此我们选择较简单的长短时间记忆模型 (LSTM: Long-short term memory) 架构加上多种时间序列作为预测模型。
我们来考虑四组从1990年到现在的数据序列:标普500 (GSPC) ,道琼斯工业平均 (DJI) ,纳斯达克综指 (IXIC) ,及代表芝加哥期权的罗素2000指数 (RUT) 。
代码行示意如下:
stock = ['^RUT', '^GSPC', '^DJI', '^IXIC' ]
start = pd.to_datetime('1990-01-03')
df = web.DataReader(stock, data_source = 'yahoo', start = start )
现在我们将如下图1所示的四组交易指数的收盘价格拟合入神经网络架构中,并由此预测一组交易指数,如纳斯达克指数的未来走向。
图1. 将四组交易指数的收盘架构拟合在神经网络架构里
二、训练组与测试组数据分离
下列代码行将训练集和测试集数据分开,并将其可视化,如图2及图3所示。
data = df [['Close']]
data = data.reset_index()
training_data = data[data['Date'] < pd.to_datetime('2016-12-31')].copy()
test_data = data[data['Date'] >= pd.to_datetime("2016-12-31")].copy()
training_data = training_data.set_index('Date')
test_data = test_data.set_index('Date')
plt.figure(figsize=(14,4))
plt.plot(training_data.Close['^RUT'])
plt.plot(test_data.Close['^RUT'])
plt.ylabel("Price")
plt.xlabel("Date")
plt.legend(["Training Set", "Test Set"])
plt.title("Chicago Options Close Price")
plt.show()
图2.将数据样本为芝加哥期权交易价格的训练数据(红色)和测试数据(蓝色)分离的可视化结果
图3.将数据样本为标普500收盘价格的训练数据(红色)和测试数据(蓝色)分离的可视化结果
同理,我们可以将数据样本为道琼斯工业平均,和纳斯达克综指收盘价格的训练数据集和测试数据集的可视化结果以图片的形式展现出来,这里我们不再过多赘述。
三、数据正则化
这里我们选用MinMaxScaler对数据进行正则化,使得所有数据的特征值都在[0,1]区间中。通常情况下,MinMaxScaler能够将数据集形状完整留存下来。有时候也可采取对数回归进行数据正则化,得到的结果可能更好。
下述代码行展示了如何用MinMaxScaler做数据正则化:
minmax = MinMaxScaler(feature_range = (0, 1))
minmax_single = MinMaxScaler(feature_range = (0, 1))
train_scaled = np.concatenate ([minmax.fit_transform (training_data.Close[['^RUT', '^GSPC', '^DJI']].values), minmax_single.fit_transform(training_data.Close[['^IXIC']].values)], axis = 1)
train_scaled = pd.DataFrame(train_scaled, columns = training_data.columns)
train_scaled
得出的结果为:
train_scaled.describe() # validating min & max values
来看一段用lognormal来做数据正则化的代码及可视化结果:
图5. 用lognormal做数据正则化的代码截行及可视化结果
四、数据定形
下述为数据定形的代码及其输出结果:
train_scaled = train_scaled.values
n_lags = int(60)
X_train = []
y_train = []
for i in range(n_lags, train_scaled.shape[0]):
X_train.append(train_scaled[i-n_lags:i])
y_train.append(train_scaled[i,0])
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], 4))
# Check the shape (again) before start training
shape_chk = []
for i in stock:
index = {}
index["X_train"] = X_train.shape
index["y_train"] = y_train.shape
shape_chk.append(index)
pd.DataFrame(shape_chk, index=stock)
五、神经网络架构训练
现在我们输入1990年至2015年的数据,用来训练神经网络架构:
%%time
# The LSTM architecture
regressor = Sequential()
# 1st layer with Dropout regularisation
regressor.add(LSTM(units=20, return_sequences=True, input_shape=(X_train.shape[1],4)))
regressor.add(Dropout(0.2))
# 2nd LSTM layer
regressor.add(LSTM(units=20, return_sequences=True))
regressor.add(Dropout(0.2))
# 3rd LSTM layer
regressor.add(LSTM(units=20, return_sequences=True))
regressor.add(Dropout(0.5))
# 4th LSTM layer
regressor.add(LSTM(units=20))
regressor.add(Dropout(0.5))
# Output layer
regressor.add(Dense(units=1))
# Compiling LSTM
regressor.compile(optimizer='adam', loss='mean_squared_error')
# Fitting to the training set
for i in stock:
print("Fitting to", i)
regressor.fit(X_train, y_train, epochs=10, batch_size=100)
Fitting to ^IXIC Epoch 1/10 6492/6492 [=======================================] — 8s 1ms/step — loss: 0.0036 Epoch 2/10 6492/6492
[=======================================] — 8s 1ms/step — loss: 0.0037 Epoch 3/10 6492/6492
[=======================================] — 8s 1ms/step — loss: 0.0036 Epoch 4/10 6492/6492
[=======================================] — 8s 1ms/step — loss: 0.0035 Epoch 5/10 6492/6492
[=======================================] — 8s 1ms/step — loss: 0.0037 Epoch 6/10 6492/6492
[=======================================] — 8s 1ms/step — loss: 0.0035 Epoch 7/10 6492/6492
[=======================================] — 8s 1ms/step — loss: 0.0036 Epoch 8/10 6492/6492
[=======================================] — 8s 1ms/step — loss: 0.0035 Epoch 9/10 6492/6492
[=======================================] — 8s 1ms/step — loss: 0.0035 Epoch 10/10 6492/6492
[=======================================] — 8s 1ms/step — loss: 0.0038 CPU times: user 9min 55s, sys: 27.5 s, total: 10min 22s Wall time: 5min 43s
六、测试组数据预测股票走向
为了预测股票未来走向,我们要进行下述四步操作:
-
将训练集和测试集数据融合在一起,并对齐0轴;
-
将n_tag作为时间步;
-
将新数据集做转换;
-
重新定形数据集。
1、测试数据转换
下列代码行是为了将测试数据做转换:
total_data = pd.concat((training_data, test_data), axis = 0)
inputs = total_data[len(total_data) - len(test_data) - 60:]
test_scaled = np.concatenate([minmax.transform(inputs.Close[['^RUT', '^IXIC', '^DJI']]),
minmax_single.transform(inputs.Close[['^GSPC']])], axis = 1)
print('Shape of test data:', test_scaled.shape)
# shaping data from neural network
X_test = []
y_test = []
for i in range(60, test_scaled.shape[0]):
X_test.append(test_scaled[i-n_lags:i])
y_test.append(test_scaled[i,0])
X_test, y_test = np.array(X_test), np.array(y_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 4))
2、预测
做完预测后,我们需要将转换后的数据再转成可读取的格式,以显示预测价格:
predicted_price = regressor.predict(X_test)
predicted_price = minmax_single.inverse_transform(predicted_price)
predicted_price = pd.DataFrame(predicted_price)
predicted_price.rename(columns = {0: 'Nasdaq_predicted'}, inplace=True)
predicted_price = predicted_price.round(decimals=0)
predicted_price.index = test_data.index
3、可视化
下列代码为可视化代码:
plt.figure(figsize = (14,5))
mse = mean_squared_error(y_test, predicted_price)
plt.plot(predicted_price['Nasdaq_predicted'], color = 'red', label = 'Predicted Nasdaq closing price')
plt.plot(test_data.Close['^IXIC'], color = 'green', label = 'Actual Nasdaq closing price')
plt.title ("Nasdaq Composite closing Price prediction- with MSE {:10.4f}".format(mse))
plt.xlabel('Time')
plt.ylabel('Price (USD)')
plt.legend()
图6展示了股票预测的可视化效果:
图6. 股票预测的可视化结果呈现
如图所示,我们训练好的神经网络是可以较好得寻找出数据之间的隐藏关系,并进行趋势预测,然而预测的精度还有待提高,需要选取更加正确的参数。
对于其他指数的价格走向,按照上述的工作流程,也可以进行预测,小伙伴们如有兴趣,可以自己尝试一下。
七、结论
我们可以看出,深度学习的神经网络,对于预测股票价格趋势而言,确实是个强有力的工具,它能够发现数据间的隐藏动态关系,并基于发现的模式进行预测。
为了简单说明工作流的工作方式,我们仅仅拟合了一个简单的LSTM网络架构,且并未优化任何参数。如果要构建一个鲁棒性更加高的神经网络,我们还需要选取正确的参数,如epoch,batch size,neurons,hidden layers的数量到底为多少,才能得出最优的精确度。