本文为 AI 研习社编译的技术博客,原标题 : Neural Networks to Predict the Market 翻译 | 老赵 校对 | 酱番梨 整理 | 菠萝妹 原文链接: https://towardsdatascience.com/neural-networks-to-predict-the-market-c4861b649371
注:本文的相关链接请点击文末【阅读原文】进行访问
机器学习和深度学习已经成为量化对冲基金常用最大化其利润的常用的新的有效策略。 作为一名人工智能和金融爱好者,这是令人振奋的消息,因为它结合了我感兴趣的两个领域。 本文将介绍如何使用神经网络预测股票市场,特别是股票(或指数)的价格。 这篇文章基于我的GitHub中的python项目,在那里你可以找到完整的python代码以及如何使用该程序。 此外,对于更多这样的内容,请查看我自己的页面:Engineer Quant
金融是高度非线性的,有时股票价格数据甚至可能看起来完全随机。 传统的时间序列方法(如ARIMA和GARCH模型)仅在序列是静止时才有效,这是一个限制性假设,需要通过记录返回(或其他变换)对序列进行预处理。 然而,主要问题出现在实时交易系统中实施这些模型,因为在添加新数据时无法保证平稳性。
这通过使用神经网络来对抗,它不需要使用任何平稳性。 此外,神经网络本质上有效地找到数据之间的关系并使用它来预测(或分类)新数据。
典型的完整堆栈数据科学项目具有以下工作流程:
1. 数据采集 - 这为我们提供特征
2. 数据预处理 - 使数据可用的必要步骤但常常是复杂的
3. 开发和实施模型 - 我们选择神经网络和参数的类型
4. 回测模型 - 任何交易策略中非常关键的一步
5. 优化 - 找到合适参数
我们的神经网络的输入数据是过去十天的股票价格数据,我们用它来预测明天的股票价格数据。
幸运的是,该项目所需的股票价格数据在雅虎财经中随时可用。 可以使用他们的Python API获取数据,或直接从他们的网站得到。
在我们的案例中,我们需要将数据分解为十个价格和第二天价格的训练集。 我通过定义一个类来完成这个,
将其分解为训练和测试数据并定义方法。
在给定特定长度的窗口(在我们的例子中为10)的情况下,将训练数据(输入和输出)作为数组返回。
完整代码如下:
def gen_train(self, seq_len):
for i in range((len(self.stock_train)//seq_len)*seq_len - seq_len - 1):
x = np.array(self.stock_train.iloc[i: i + seq_len, 1])
y = np.array([self.stock_train.iloc[i + seq_len + 1, 1]], np.float64)
self.input_train.append(x)
self.output_train.append(y)
self.X_train = np.array(self.input_train)
self.Y_train = np.array(self.output_train)
同样,对于测试数据,我定义了一个方法返回测试数据
和
对于这个项目,我使用了两种神经网络模型:多层感知器(MLP)和长短期模型(LSTM)。 我将简要介绍这些模型的工作原理,但是要了解MLP的工作原理,请查看本文。 对于LSTM,请查看Jakob Aungiers撰写的这篇优秀文章。
MLP是最简单的神经网络形式,其中输入被反馈送到模型中,并且使用特定权重,值通过隐藏层向前馈送以产生输出。 学习来自于通过隐藏层反向传播以改变每个神经元之间权重的值。 MLP的一个问题是缺乏“记忆”。 对以前的训练数据中发生的事情没有任何意义,以及这可能会如何影响新的训练数据。 在我们的模型的上下文中,一个数据集中的十天数据与另一个数据集之间的差异可能很重要(例如)但是MLP没有分析这些关系的能力。
这就是LSTM或一般的递归神经网络(RNN)的发挥作用之处。RNN能够存储有关数据的某些信息供以后使用,这扩展了网络分析股票价格数据之间关系的复杂结构的能力。 RNN的一个问题是梯度消失问题。 这是因为当层数增加时,学习率(值小于1)被乘以几次,这导致梯度不断减小。 LSTM对此进行了抑制,使其更有效。
为了实现模型,我选择了
因为它使用了向网络添加层而不是一次定义整个网络的想法。 这使我们能够快速更改层数和层类型,这在优化网络时非常方便。
使用股票价格数据的一个重要步骤是规范化数据。 这通常意味着你减去平均值并除以标准差,但在我们的情况下,我们希望能够在一段时间内在实时交易中使用该系统。 因此,采用统计时刻可能不是规范化数据的最准确方法。 所以我只将整个数据除以200(任意数字使得一切都变小)。 虽然似乎标准化是凭空产生的,但它仍然有效地确保神经网络中的权重不会变得太大。
让我们从更简单的MLP开始。 在这之中
这是通过制作顺序模型并在其上添加密集层来完成的。 完整代码如下:
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(100, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(100, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(1, activation=tf.nn.relu))
model.compile(optimizer="adam", loss="mean_squared_error")
这就是keras的好处所在。 只需要这五行代码,我们就创建了一个带有两个隐藏层的MLP,每个层都有一百个神经元。 关于优化器的一点说法。 Adam优化器在机器学习社区中越来越受欢迎,因为与传统的随机梯度下降相比,它是一种更有效的优化算法。 通过观察随机梯度下降的另外两个扩展的优点,可以最好地理解这些优点:
Adam可以被认为是结合上述扩展的好处,这就是为什么我选择使用Adam作为我的优化器。
现在我们需要将模型与我们的训练数据相匹配。 同样,keras使它变得简单,只需要以下代码:
model.fit(X_train, Y_train, epochs=100)
一旦适合我们的模型,我们需要根据我们的测试数据对其进行评估,以了解它的执行情况。 这是通过
model.evaluate(X_test, Y_test)
你可以使用评估中的信息来评估模型预测股票价格的能力。
对于LSTM模型,程序类似,代码如下:
model = tf.keras.Sequential()
model.add(tf.keras.layers.LSTM(20, input_shape=(10, 1), return_sequences=True))
model.add(tf.keras.layers.LSTM(20))
model.add(tf.keras.layers.Dense(1, activation=tf.nn.relu))
model.compile(optimizer="adam", loss="mean_squared_error")
model.fit(X_train, Y_train, epochs=50)
model.evaluate(X_test, Y_test)
需要注意的一点是,keras要求输入数据具有某些尺寸,由你的模型决定。 使用numpy重新定义数据至关重要。
现在我们已经使用训练数据拟合了我们的模型,并使用测试数据对其进行了评估,我们可以通过在新数据上回溯测试模型来进一步评估。 这很简单
def back_test(strategy, seq_len, ticker, start_date, end_date, dim):
data = pdr.get_data_yahoo(ticker, start_date, end_date)
stock_data = data["Adj Close"]
errors = []
for i in range((len(stock_data)//10)*10 - seq_len - 1):
x = np.array(stock_data.iloc[i: i + seq_len, 1]).reshape(dim) / 200
y = np.array(stock_data.iloc[i + seq_len + 1, 1]) / 200
predict = strategy.predict(x)
while predict == 0:
predict = strategy.predict(x)
error = (predict - y) / 100
errors.append(error)
total_error = np.array(errors)
print(f"Average error = {total_error.mean()}")
但是,这种回溯测试是一个简化版本,而不是一个完整的回测系统。 对于完整的回测系统,你需要考虑诸如生存偏差,预测偏差,市场体制变化和交易成本等因素。 由于这仅仅是一个教育项目,简单的回测就足够了。 但是,如果你对设置完整的回测系统有疑问,请随时与我联系。
下面显示了我的LSTM模型在预测2月份Apple股票价格时的表现
对于没有优化的简单LSTM模型,这是非常好的预测。 它真实地向我们展示了神经网络和机器学习模型在建模参数之间复杂关系方面的稳健性。
优化神经网络模型对于在样本外测试中提高模型的性能通常很重要。 我没有在我的开源版本的项目中包含调优,因为我希望它对那些阅读它的人来说是一个挑战,并尝试优化模型以使其表现更好。 对于那些不了解优化的人来说,它涉及找到最大化模型性能的超参数。 有几种方法可以搜索这些理想的超参数,从网格搜索到随机方法。 我强烈认为,学习优化模型可以将您的机器学习知识提升到新的水平,因此,我将挑战你提出一个优于上图中显示的性能的优化模型。
机器学习每天都在不断发展,每天都在开发新的方法。 至关重要的是,我们不断更新我们的知识,最好的方法是为有趣的项目建立模型,如股票价格预测。 虽然上面的LSTM模型不足以用于实时交易,但通过开发这样的模型构建的基础可以帮助构建更好的模型,这些模型有一天可能会在我们的交易系统中使用。