教你打造股市晴雨表——通过LSTM神经网络预测股市

作者介绍:
Jakob Aungiers 现就职于汇丰银行伦敦总部,担任全球资产管理的开发副总裁。擅长机器学习,神经网络等领域。

(以下为译文)
谈及机器学习,神经网络无疑是当前的热门话题。因此,在网络上围绕神经网络的教程和社区多不胜数。现在虽然有大量的公共研究论文和文章涉及LSTM,但我发现,这些理论和例子并没有显示出LSTM在时间序列预测上的真正实力。有鉴于此,我决定以本文作抛砖引玉之用,使用LSTM来预测一些时间序列—例如股市(使用Keras包,对应Python版本为2.7)。
此项目的完整代码可以在GitHub页面上找到(链接)。

简单的正弦波

让我们从最基本的事情开始----标准正弦波函数。首先创建数据,然后模拟这个函数的多个振荡,以便进行LSTM网络训练。我做了一个excel电子表格,这是一个幅度和频率为1(给出角频率为6.28)的正弦波,我使用该函数获得超过5001个数据点的时间段,时间增量为0.01。其结果看起来是这样的:
(用作训练/测试文件的链接在这里

这些数据有什么用呢?LSTM将从这一组窗口大小数据值来学习正弦波,然后LSTM会据此来进行时序预测以画出n步后的波形图。

我们首先从CSV文件中转换和载入数据到numpy数组中,然后喂食LSTM。Keras LSTM层的工作方式是通过接收3维(N,W,F)的数字阵列,其中N是训练序列的数目,W是序列长度,F是每个序列的特征数目。我选择的一个序列长度(读取窗口大小)为50,这可让网络在每个序列中知道正弦波的形状,从而教会自身基于先前窗口信息的前提下建立序列的模式。序列本身是滑动的窗口,因此每次移动1长度后,会保持与先前窗口的恒定重叠。

长度为50的序列的示例

下面是将训练数据CSV加载到正确形状numpy数组中的代码:

def load_data(filename):
    f = open('sinwave.csv', 'rb').read()
    data = f.split('\r\n')

    sequence_length = 50
    result = []
    for index in range(len(data) - sequence_length):
        result.append(data[index: index + sequence_length])

    result = np.array(result)

    row = round(0.9 * result.shape[0])
    train = result[:row, :]
    np.random.shuffle(train)
    x_train = train[:, :-1]
    y_train = train[:, -1]
    x_test = result[row:, :-1]
    y_test = result[row:, -1]

    x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))
    x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1], 1))  

    return [x_train, y_train, x_test, y_test]

接下来,我们需要实际构建网络本身。我使用了[1,50,100,1]的网络结构,其中我们有1个输入层(由大小为50的序列组成),该输入层喂食50个神经元给LSTM层,接着该LSTM层喂食100个神经元给另一个LSTM层,然后使用一个线性激活函数来喂食一个完全连接的正常层以用于下一个时间步的预测。

模型构建函数代码如下:

def build_model(layers):
    model = Sequential()

    model.add(LSTM(
        input_dim=layers[0],
        output_dim=layers[1],
        return_sequences=True))
    model.add(Dropout(0.2))

    model.add(LSTM(
        layers[2],
        return_sequences=False))
    model.add(Dropout(0.2))

    model.add(Dense(
        output_dim=layers[3]))
    model.add(Activation("linear"))

    start = time.time()
    model.compile(loss="mse", optimizer="rmsprop")
    print "Compilation Time : ", time.time() - start
    return model

最后是训练网络上的数据,看看我们得到了什么。在该LSTM我只使用了1个训练时期,这有别于需要大量训练数据的传统网络。因为我们使用的是简的具可预测模式的正弦波,1训练时期将足够获得非常近似的全sin函数。

放入run.py模块后的代码:

epochs  = 1
seq_len = 50

print 'Loading data... '

X_train, y_train, X_test, y_test = lstm.load_data('sinwave.csv')

print '\nData Loaded. Compiling...\n'

model = lstm.build_model([1, 50, 100, 1])

model.fit(
    X_train,
    y_train,
    batch_size=512,
    nb_epoch=epochs,
    validation_split=0.05)

predicted = lstm.predict_point_by_point(model, X_test)

如果你注意到你会注意到我们在上面的load_data()函数中,我们将数据分为训练/测试集,这是机器学习问题的标准做法。然而,我们需要注意的是,我们实际上想要在时间序列实现预测。

如果我们使用测试集,我们将运行每个窗口的真实数据来预测下一个时间步。下图是使用该方法后的结果:

epochs = 1, window size = 50

然而,如果我们想要预测许更多的时间步,我们需使用来自测试数据的第一个窗口作为启动窗口。 在每个时间步,弹出窗口后面的最先条目,并将下一个时间步预测附加到窗口的前面,实质上是移动窗口,所以它是慢慢地用预测建立自己,直到窗口都是预测值(在我们的例子中,因为我们的窗口大小为50,这将发生在50个时间步之后)。 然后,我们无限期地保持这一点,预测下一步对未来时间步骤的预测,从而实现看到趋势预测。

下图显示了仅从真实测试数据的初始开始窗口预测的正弦波时间序列,然后预测约500步:

epochs = 1, window size = 50

除了简单的正弦波预测,LSTM还能做更复杂的预测吗?答案是肯定的,例如以下的有关股票市场的时间序列预测。什么?!股票预测!!是的。这是LSTM另一个技能--潜在隐藏趋势预判。

首先我准备了一个CSV文件(链接),其保存的是标准普尔500股权指数从2000年1月到2016年8月的收盘数据。我使它与我们的正弦波数据具完全相同的格式,然后运行相同的模型。

这之前我们需要对我们的数据做一个微小的改变,因为正弦波已经是一个很规范的重复模式,但股票数据是不规范的。因此为了应对这种情况,我们需要使训练/测试数据的每个n大小的窗口进行标准化,以反映从该窗口开始的百分比变化(因此点i = 0处的数据将始终为0)。我们将使用以下方程式进行归一化,然后在预测过程结束时进行反标准化,以得到预测中的真实世界数:

n =价格变化的标准化列表[窗口]
p =原始列表[窗口]调整的每日回报价格
标准化公式:
-1)

反标准化公式:
)

在代码中添加一个normalise_windows(window_data)函数,并更新load_data(filename)函数以包含一个条件调用,以及获取序列长度和规范化标志load_data(filename,seq_len,normalise_window):

代码如下:

def load_data(filename, seq_len, normalise_window):
    f = open(filename, 'rb').read()
    data = f.split('\r\n')

    sequence_length = seq_len + 1
    result = []
    for index in range(len(data) - sequence_length):
        result.append(data[index: index + sequence_length])

    if normalise_window:
        result = normalise_windows(result)

    result = np.array(result)

    row = round(0.9 * result.shape[0])
    train = result[:row, :]
    np.random.shuffle(train)
    x_train = train[:, :-1]
    y_train = train[:, -1]
    x_test = result[row:, :-1]
    y_test = result[row:, -1]

    x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))
    x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1], 1))  

    return [x_train, y_train, x_test, y_test]

def normalise_windows(window_data):
    normalised_data = []
    for window in window_data:
        normalised_window = [((float(p) / float(window[0])) - 1) for p in window]
        normalised_data.append(normalised_window)
    return normalised_data

归一化了如上所述的窗口后,我们现在可以通过LSTM网络运行我们的股票数据。 让我们看看它的运行情况:

在如上所述的单个逐点预测上运行数据给出了与实际相当接近的图形。但这是欺骗性的!为什么?如果你更仔细地看,预测线由单一的预测点组成,它们在它们之后具有整个先前的真实历史窗口。因此,网络并不依赖时间序列本身,除了每下一个点可能不会离最后一点太远。因此,即使它得到错误预测的点,下一个预测可在考虑真实历史后忽略不正确的预测,并允许再次出现错误。

那么,我们来看看是否真的有一些潜在的模式在价格中变动切可辨别?接下来让我们做对正弦波问题做的同样事情,让网络预测点序列而不是下一个点。

这样,我们现在可以看到,与作为正弦波序列的正弦波不同,它与真实数据几乎相同,我们的股票数据预测很快地收敛到某种平衡。

epochs = 50, window size = 50

epochs = 1, window size = 50

让我们进一步研究回归收敛,将我们的预测序列限制到50个未来时间步长,然后每次将启动窗口移动50单位:

epochs = 1, window size = 50, sequence shift = 50

而当epochs增加到400时(这应该使模型模式更准确),我们看到,实际上它现在只是试图预测几乎每个时间段的向上动量。

epochs = 400, window size = 50, sequence shift = 50

小结:
LSTM的应用日益广泛,例如文本预测,AI智能聊天,自驾车等许多前沿领域。 希望本文能有助你开拓LSTM在时间序列中应用的视野。

本文由北邮@爱可可-爱生活 老师推荐,阿里云组织翻译。
文章原标题《LSTM NEURAL NETWORK FOR TIME SERIES PREDICTION》,作者:Jakob Aungiers ,译者:伍昆

文章为简译,更为详细的内容,请查看原文

时间: 2024-10-27 16:19:47

教你打造股市晴雨表——通过LSTM神经网络预测股市的相关文章

新手教程之:循环网络和LSTM指南 (A Beginner’s Guide to Recurrent Networks and LSTMs)

  新手教程之:循环网络和LSTM指南 (A Beginner's Guide to Recurrent Networks and LSTMs)   本文翻译自:http://deeplearning4j.org/lstm.html   其他相关教程: 1. 深度神经网络简介 http://deeplearning4j.org/zh-neuralnet-overview 2. 卷积网络 http://deeplearning4j.org/zh-convolutionalnets   目录: 1.

教你打造性感无比的PPT封面

今天给大家分享一个来自PPT达人面包的教程,一个手把手教你打造一款性感无比的PPT封面.这个PPT封面的灵感来源:是11月20日在逛淘宝的时候无意间看到的,觉得设计感不错,而且PPT可以非常容易的实现,所以今天给大家分享这种类型的版面设计. 先看上面这个图,我们先分析一下PPT页面构成的元素. 1.有质地的底纹; 2.底纹有渐变的效果,中间较亮,周边暗,可以起到聚焦的作用; 3.虚线的描边; 4.倾斜的字体; 5.不规则带阴影的图形(日期). OK,如果这儿东西继续演变下去,作为PPT模板,最核

教大家打造一只梦幻创意星空眼睛效果

  教大家打造一只梦幻创意星空眼睛效果,要用到PS+SAI软件,纯数表也可以画完.有手绘板就更好画 分类: PS入门教程

LSTM神经网络

LSTM是什么 LSTM即Long Short Memory Network,长短时记忆网络.它其实是属于RNN的一种变种,可以说它是为了克服RNN无法很好处理远距离依赖而提出的. 我们说RNN不能处理距离较远的序列是因为训练时很有可能会出现梯度消失,即通过下面的公式训练时很可能会发生指数缩小,让RNN失去了对较远时刻的感知能力. ∂E∂W=∑t∂Et∂W=∑tk=0∂Et∂nett∂nett∂st(∏tj=k+1∂st∂sk)∂sk∂W 解决思路 RNN梯度消失不应该是由我们学习怎么去避免,而

三步教你搭建给黑白照片上色的神经网络 !(附代码)

深度学习云平台FloydHub最近在官方博客上发了一篇通过搭建神经网络,来给黑白照片上色的教程,在Twitter和Reddit论坛上都广受好评. FloydHub是个YC孵化的创业公司,号称要做深度学习领域的Heroku.它在GPU系统上预装了TensorFlow和很多其他的机器学习工具,用户可以按时长租用,训练自己的机器学习模型.免费版支持1个项目.每月20小时GPU时长.10G存储空间,用上色项目练个手足够了. 进入正题~ 以下内容编译自FloydHub官方博客: 我将分三个步骤展示如何打造

30分钟教您打造自己的代码生成器

原文:30分钟教您打造自己的代码生成器             哇咔咔,离上次写文又有几个月了.不过上次写的<这些开源项目,你都知道吗?(持续更新中...)[原创]>受到广大读者的赞赏和推荐,也使得自己更有动力去写技术文章.好了,废话不多说,直接切入正题.       前方高能预警,由于此篇博文适合初学者入门或者各种大牛老男孩怀念那些年我们一起写过的代码生成器,所以请各路时间宝贵的大神慎重查看此篇博文,误入者后果自负!!!  一.前言背景(3分钟)       博主清晰的记得,大三的时候,老师

三步教你打造非主流照片效果

三步教你打造非主流照片,今天是用最简单的方法快速的用ps把照片制作成非主流效果照片的教程了. 好了来看制作教程吧.用减淡工具,如下图设置. 再对MM脸进行一下下,如上图.

老班:手把手教你打造完美符合SEO的博客(三)

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 老班在前面两讲<老班:手把手教你打造完美符合SEO的博客(一) >与<老班:手把手教你打造完美符合SEO的博客(二) >主要讲了: 1.博客的策划(长期计划与短期计划) 2.如何选择博客程序(选择自己合适的,才是最好的) 这一讲的内容是:如何确定博客的主题. 写博如果仅仅是个兴趣而已,或者仅仅把它当做写日记一样看待.我

微博人群分“血型”粉丝心情或成股市晴雨表

"你有微博吗?加我关注!"随着微博风行,这已成了时下最流行的网络问候语. 微时代,如何玩转微博?如何快速增加自己的粉丝?想不想让自己的微博被成百上千次地转发和评论?想不想被自己的偶像关注,与他(她)亲密互动?日前,在浙报报告厅,来自武汉大学信息管理学院的教授.博导沈阳老师对微博时代的传播规律进行了深入浅出的分析. 目前,新浪微博的用户已经突破2亿,在如此庞大的数字中,其实大致可以分为4种不同性格类型,我们不妨称 它们作"微博血型". "自我表达型"