本期作者:Alexandre Xavier
本期翻译:Remedios | 公众号翻译部
近期原创文章:
前言
在这篇文章中,我们会使用神经网络,特别是LSTM模型,来预测时间序列。
尽管预测股价确实是一个老问题,至今仍然没有被解决。事实十分简单:股票的价格由多种因素决定,而股票的历史价格仅仅是众多原因中的一小部分。因此,预测股价走势是一个非常困难的问题。
获取全部代码见文末:
摘要
首先,我将使用一些数据可视化工具介绍数据集。然后,我们将大致讨论使用移动平均算法预测股票市场走势有多难并且展示其局限性。接下来,我们将对RNN和LSTM的做一个简短的介绍,并举一个预测单个公司股价的LSTM实例。最后,我们会展示使用LSTM同时预测四个公司的股价,并且比较结果以探究是否预测效果会随着我们预测股价的公司个数的增加而提升。
数据可视化
本文使用的数据集是以CSV格式从雅虎财经下载下来的,其中包括四个公司从2010年1月8日到2019年1月7日的股价。我们将这四个公司分别称为A,B,C和D.
基础步骤是用Pandas打开这个CSV文件。我们先看一下这些数据:
df_A = pd.read_csv(‘data/company_A.csv’)
df_A[‘Date’] = pd.to_datetime(df_A[‘Date’])
df_A.head()
plt.figure(figsize = (15,10))
plt.plot(df_A['Date'], df_A['Close'], label='Company A')
plt.plot(df_B['Date'], df_B['Close'], label='Company B')
plt.plot(df_C['Date'], df_C['Close'], label='Company C')
plt.plot(df_D['Date'], df_D['Close'], label='Company D')
plt.legend(loc='best')
plt.show()
四个公司的收盘价
移动平均
用于股价预测的一个经典算法是移动平均值(MA)。这个方法主要在于计算过去“m”个观察日的平均值,并且使用此结果作为下一日的预测值。作为举例,使用过去10天和20天的收盘价计算移动平均值。
df['MA_window_10'] = df['Close'].rolling(10).mean().shift()
df['MA_window_20'] = df['Close'].rolling(20).mean().shift()
当我们尝试使用移动平均值对未来10天股票的收盘价进行预测时,结果如下:
获取全部代码,见文末
window_size = 10
forward_days = 10 # > 1, ou seja, 2,3,4,5,...for index in range(window_size, len(df), forward_days):for i in range(0,forward_days):if index+i >= len(df):break
window_close = make_window(window_size-i, index+i-window_size)#print(window_close)
window_MA = make_window(i, index)#print(window_MA)
mean = pd.concat([ df['Close'].iloc[window_close], df['MA_window_10_forward_10'].iloc[window_MA] ]).mean(axis=0)
df.iat[index+i, df.columns.get_loc('MA_window_10_forward_10')] = mean
plt.figure(figsize = (15,10))
size = len(df)-limit - (len(df)-limit)%forward_daysfor index in range(size, len(df), forward_days):
plt.plot(df['MA_window_10_forward_10'][index:index+forward_days], color='r')
plt.plot(df['Close'][-limit:], color='b', label='Close')#plt.legend(loc='best')
plt.show()
使用移动平均对公司A股票的十日收盘价预测
注意每条红线代表一个基于过去十天数据的10日股价预测。因此,红线是不连续的。
使用一个稍微更好一点的算法,指数移动平均(EMA),我们可以对预测实现一点点改善:
使用指数移动平均对公司A股票收盘价进行提前一天预测结果
对比MA和EMA:
提前一天使用移动平均和指数移动平均对股票收盘价进行预测结果对比
这个方法过于简单。我们真正想要的是提前“n”天预测未来的走势,这个任务MA和EMA都无法做到。
RNN
要理解LSTM网络,我们首先需要理解RNN。这种网络被用于过去结果对目前结果有影响时的模式识别。时间序列函数是RNN的一个运用实例。在这个函数中,数据顺序极其重要。
在这个网络架构中,神经元不仅使用普通的输入(即前一层的输出),也使用它之前的状态作为输入。
RNN结构
需要注意的是,“H”代表神经元的状态。因此,在状态H1,神经元使用参数X1和H0(它之前的状态)作为输入。这个模型的主要问题是记忆的损失。之前的网络状态将会被更快地遗忘。在我们需要记忆前序信息之前的信息的序列中,RNN无法记忆。
LSTM
LSTM源于RNN,但是它能够通过改变神经元架构解决记忆的损失。
LSTM结构
新的神经元有三个门,每一个有不同的功能。这些门分别是:
输入门
输出门
遗忘门
每个LSTM神经元依然将它之前的状态作为输入:
LSTM神经元让它之前状态的参数通过
使用LSTM预测单个公司股价
最后,让我们使用一个LSTM来预测公司A单个公司股价的走势。
首先来看以下这些参数。我们想要利用m日过去的数据(look_back)对未来n天(forward_days)的股价进行预测。所以,如果我们有m天过去数据的输入值,这个网络的输出值会是之后n天股价的预测值。我们将数据集划分为训练集和测试集。训练集将由k个周期组成(num_periods),每个周期中有一系列的n日预测。
look_back = 40
forward_days = 10
num_periods = 20
现在,让我们用Pandas打开这个CSV文件并且只保留我们会用到的日期和收盘价两列。公司A初始的收盘价作图如下:
plt.figure(figsize = (15,10))
plt.plot(df)
plt.show()
我们依次衡量输入值的比例,将数据划分成训练集/验证集和测试集,并进行格式化来反馈给模型。详细过程可以在文末代码上找到。
现在,我们建立并训练这个模型。
获取全部代码,见文末
NUM_NEURONS_FirstLayer = 128
NUM_NEURONS_SecondLayer = 64
EPOCHS = 220#Build the model
model = Sequential()
model.add(LSTM(NUM_NEURONS_FirstLayer,input_shape=(look_back,1), return_sequences=True))
model.add(LSTM(NUM_NEURONS_SecondLayer,input_shape=(NUM_NEURONS_FirstLayer,1)))
model.add(Dense(foward_days))
model.compile(loss='mean_squared_error', optimizer='adam')
history = model.fit(X_train,y_train,epochs=EPOCHS,validation_data=(X_validate,y_validate),shuffle=True,batch_size=2, verbose=2)
结果得到:
看看测试集:
注意每条红线代表基于过去40天的十日预测。我们选择在20个周期上测试,因而有20根红线。这就是为什么红色的预测线不连续。
通过对所有公司重复以上相同的流程,测试集的最好结果出现在对公司C的预测。
尽管这是这之间最好的模型,结果还远远不够优秀。可能导致这个结果的理由有很多,其中的一些可能是:
仅仅用收盘价历史数据不足以预测股价走势
这个模型还能被进一步改善
使用LSTM预测四个公司的股价
最后,我们将用LSTM模型来一起预测所有四个公司的股价走势,并将结果与LSTM预测单个公司的结果进行对比。目标是分析是否使用来自几个不同公司的数据能够提高对个个公司股价的预测。
需要指出的是,所有四个CSV文件有相同的日期。这样以来,网络不会从一家公司接收未来讯息来预测另一家公司的价值。
在数据正则化并格式化,反馈给模型之后,这个模型被训练:
NUM_NEURONS_FirstLayer = 100
NUM_NEURONS_SecondLayer = 50
EPOCHS = 200#Build the model
model = Sequential()
model.add(LSTM(NUM_NEURONS_FirstLayer,input_shape=(look_back,num_companies), return_sequences=True))
model.add(LSTM(NUM_NEURONS_SecondLayer,input_shape=(NUM_NEURONS_FirstLayer,1)))
model.add(Dense(foward_days * num_companies))
model.compile(loss='mean_squared_error', optimizer='adam')
history = model.fit(X_train,y_train,epochs=EPOCHS,validation_data=(X_validate,y_validate),shuffle=True,batch_size=1, verbose=2)
结果:
仔细看测试集:
到了比较结果的时候了。单个公司LSTM模型的结果放在左边,四个公司LSTM模型的结果放右边遍。第一条线展示的是测试集中的预测,第二条线是所有数据集的预测。
公司A
公司B
公司C
公司D
总结
仅仅使用股票的历史价格预测证券市场的走势是不可能的。LSTM预测仍然令人不合意。甚至当利用多个公司的历史股价预测时,预测结果更加糟糕。
The original:https://medium.com/infosimples/predicting-stock-prices-with-lstm-349f5a0974d4
参考资料
[1] https://www.datacamp.com/community/tutorials/lstm-python-stock- market
[2] http://colah.github.io/posts/2015-08-Understanding-LSTMs/
[3] https://towardsdatascience.com/train-validation-and-test-sets- 72cb40cba9e7
[4] https://machinelearningmastery.com/diagnose-over12tting-under12tting- lstm-models/
[5] https://machinelearningmastery.com/reshape-input-data-long-short- term-memory-networks-keras/
推荐阅读
01、经过多年交易之后你应该学到的东西(深度分享)
02、监督学习标签在股市中的应用(代码+书籍)
03、全球投行顶尖机器学习团队全面分析
04、使用Tensorflow预测股票市场变动
05、使用LSTM预测股票市场基于Tensorflow
06、美丽的回测——教你定量计算过拟合概率
07、利用动态深度学习预测金融时间序列基于Python
08、Facebook开源神器Prophet预测时间序列基于Python
09、Facebook开源神器Prophet预测股市行情基于Python
10、2018第三季度最受欢迎的券商金工研报前50(附下载)
11、实战交易策略的精髓(公众号深度呈现)
12、Markowitz有效边界和投资组合优化基于Python
13、使用LSTM模型预测股价基于Keras
14、量化金融导论1:资产收益的程式化介绍基于Python
15、预测股市崩盘基于统计机器学习与神经网络(Python+文档)
16、实现最优投资组合有效前沿基于Python(附代码)
17、精心为大家整理了一些超级棒的机器学习资料(附链接)
18、海量Wind数据,与全网用户零距离邂逅!
19、机器学习、深度学习、量化金融、Python等最新书籍汇总下载
20、各大卖方2019年A股策略报告,都是有故事的人!
如何获取代码
在后台输入
20190216
后台获取方式介绍
扫码关注我们