在本文中,我们将使用神经网络,特别是LSTM模型来预测时间序列数据的行为。需要解决的问题是经典的股市预测。所有使用的数据和代码都可以私信我。

虽然这是一个老问题,但直到今天仍未解决。事实很简单:股价是由几个因素决定的,历史股价只是其中的一小部分。因此,预测价格行为是一个非常棘手的问题。

摘要

首先,我将介绍一些数据可视化
的数据集。然后,我将简要讨论使用移动平均算法预测股票市场行为的难易程度及其局限性。接下来,简要介绍递归神经网络和LSTM的概念,并以LSTM为例对单个公司
的股价进行了预测。最后,我将展示用于同时预测4家公司价格的LSTM,并比较结果,看看随着我们同时使用更多公司,预测是否有所改善。

数据可视化

数据集是从Yahoo
Finance以CSV格式下载的。它具有4个公司的股票价格在01/08/2010至01/07/2019期间。我们将它们称为公司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.tail() 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()
4家公司的所有股票收盘价

移动平均线

在这个问题中使用的一个经典算法是移动平均线(MA)。它包括计算m过去观察天数的平均值,并用这个结果作为第二天的预测。为了证明这一点,这里有一个移动平均线的例子,使用m作为公司收盘价的10和20天。
df['MA_window_10'] = df['Close'].rolling(10).mean().shift() #shift so the day
we want to predict won't be useddf['MA_window_20'] =
df['Close'].rolling(20).mean().shift()
使用移动平均线对A公司的收盘价进行一步预测

当我们尝试使用移动平均线预测未来10天的收盘价时,结果如下:

使用移动平均线对公司A的10天收盘价预测

每条红线代表基于过去10天的预测。因此,红线是不连续的。

使用指数移动平均线(EMA),我们实现了一些小的改进:

使用指数移动平均线对公司A的收盘价进行一步预测。

对比MA和EMA:

使用MA和EMA对A公司收盘价的一步预测的比较

这种方法很简单。我们真正想要的是提前n天预测股票的未来走势,MA和EMA都无法完成这项任务。

递归神经网络(RNN)

要了解LSTM网络,我们首先需要了解递归神经网络。当过去的结果对当前结果有影响时,这种网络用于识别模式。RNN使用的一个例子是时间序列函数,其中数据顺序非常重要。

在这种网络架构中,神经元不仅使用常规输入(前一层输出)作为输入,还使用其先前状态作为输入。

RNN架构

要注意H代表神经元状态。因此,当处于状态H_1时,神经元使用参数X_1和H_0(其先前状态)作为输入。该模型的主要问题是记忆丧失。旧的状态很快就会被遗忘。在我们需要记住刚刚过去的序列中,RNN无法记住。

LSTM网络

LSTM网络起源于RNN。但它可以通过改变神经元架构来解决记忆丧失。

LSTM神经元架构

新神经元有3个门,每个门都有不同的目标。门是:

* 输入门
* 输出门
* 忘记门
LSTM神经元仍然接收其先前状态作为输入:

LSTM神经元n作为参数传递其先前的状态。

LSTM预测单个公司

最后,让我们使用LSTM来预测公司A的行为。

但首先,考虑以下参数。我们希望预测未来n天(foward_days)输入过去观察到的m天(look_back)。所以,如果我们有过去m天的输入,网络输出将是未来n天的预测。我们将在Train和Test中对数据进行拆分。测试将由k个周期(num_period)组成,其中每个周期都是一系列的n天预测。
look_back = 40forward_days = 10num_periods = 20
现在,我们用Pandas打开CSV文件,只保留我们将使用的列,即日期和收盘价。A公司的初始收盘价图表是:
plt.figure(figsize = (15,10))plt.plot(df)plt.show()
A公司的收盘价

按照顺序,我们对输入进行缩放,在Train/Validation和Test中对数据进行拆分,并将其格式化以提供模型。

现在,我们构建并训练模型。
NUM_NEURONS_FirstLayer = 128NUM_NEURONS_SecondLayer = 64EPOCHS = 220#Build the
modelmodel =
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)
得到的结果是:

A公司的模型适用于所有数据

仔细观察测试集:

A公司的模型适用于测试集

请注意,每条红线表示一个基于过去40天(look_back)的10天预测(forward -
days)。有20条红线,因为我们选择在20个周期(num_periods)上进行测试。这就是为什么红色的预测线是不连续的。

通过对所有公司重复相同的过程,测试集上的最佳结果是对公司C的预测:

C公司的模型适用于测试集

尽管这是最好的模型,但结果并不是很好。可能导致这一结果的原因很多。其中一些可能是:

* 只有收盘价的历史数据不足以预测股价
* 模型还可以进行改进
LSTM预测4家公司

最后,我们将使用LSTM模型预测所有4家公司的行为,A,B,C和D,并与单一的LSTM公司结果形成对比。目的是分析使用来自多家公司的数据是否可以改善每家公司的个人预测。

需要指出的是,所有4个csv都有相同的日期。这样,网络就不会收到来自一家公司的未来信息来预测另一家公司的价值。

初始数据是:

所有4家公司的收盘价

对模型进行数据归一化和格式化之后,对模型进行训练:
NUM_NEURONS_FirstLayer = 100NUM_NEURONS_SecondLayer = 50EPOCHS = 200#Build the
modelmodel =
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)
结果是:

4家公司LSTM模型的结果

仔细观察测试集:

4家公司LSTM模型的测试集预测

是时候对比结果了。单个公司LSTM的结果显示在左侧,4个公司LSTM的结果显示在右侧。第一行显示测试集中的预测,第二行显示所有数据集中的预测。

A公司

B公司

C公司

D公司

结论

仅仅用历史价格来预测股票市场的行为是不可能的。LSTM的预测是不可接受的。即使使用几家公司的历史价格,预测也变得更糟。

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信