专栏首页量化投资与机器学习神经网络在算法交易上的应用系列——多元时间序列

神经网络在算法交易上的应用系列——多元时间序列

本期作者:Alexandr Honchar

本期翻译:yana | 公众号翻译部

这是公众号关于神经网络在金融领域特别是算法交易上的一个连载系列:

1、简单时间序列预测(已发表) 2、正确的时间序列预测+回测(已发表) 3、多变量时间序列预测 4、波动率预测和自定义损失函数 5、多任务和多模式学习 6、超参数优化 7、用神经网络增强传统策略 8、概率编程和Pyro进行预测

欢迎大家关注公众号查看此系列。本期我们从讲第三部分。

前言

之前的文章已经介绍了几种预测时间序列的方法:如何规范化数据,以实值或二进制变量的形式进行预测,以及如何处理高噪声中的过拟合。在上一篇文章中,我们只用了经过一些转换的收盘价,如果我们考虑历史数据中的最高价、最低价、开盘价、成交量,将会发生什么?这引出我们处理多元时间序列,每个时间点不止一个变量。在例子中,我们将使用整个OHLCV元组。

这篇文章中,我们会看看如何处理多元时间序列,特别是怎么处理每一个维度,如何对这种数据定义并训练一个神经网络,与上一篇文章比较结果。

数据准备

为了更好地理解什么是多元时间序列,我们看看用图形是怎么表示的,事实上图片不止二维(长和宽),还有代表颜色通道的“深度”。

在时间序列的例子中,我们的图片只是1维的(通常在图表上的情况),通道扮演不同值的角色——操作的开盘价,最高价,最低价,收盘价和成交量。你也可以从另一个视角审视它,在任意时间点,时间序列代表的不只是一个值,而是一个向量(每日开盘价,最高价,最低价,收盘价和成交量)。但是,比作图片更利于我们理解,为什么我们今天使用卷积网络来处理这个问题。

关于多元时间序列,重点之一是数据维度可以有不同数据源,不同的数据属性,完全无关和不同的分布。所以必须把它们各自归一化。

我们不需要预测一些精确的值,所以我们对未来的期望值和方差并不是很感兴趣——我们只需要预测上下幅度。这就是为什么我们会冒险只通过他们的均值和方差(z-分数 归一化)来归一化30天窗口,假设在单一时间窗口内,这些值改变不大,且没有触碰未来信息。

但我们将分别规范化时间窗的每个维度:

for i in range(0, len(data_original), STEP): 
    try:
        o = openp[i:i+WINDOW]
        h = highp[i:i+WINDOW]
        l = lowp[i:i+WINDOW]
        c = closep[i:i+WINDOW]
        v = volumep[i:i+WINDOW]
        o = (np.array(o) - np.mean(o)) / np.std(o)
        h = (np.array(h) - np.mean(h)) / np.std(h)
        l = (np.array(l) - np.mean(l)) / np.std(l)
        c = (np.array(c) - np.mean(c)) / np.std(c)
        v = (np.array(v) - np.mean(v)) / np.std(v)

但是因为我们想要预测第二天价格上涨还是下跌,所以需要考虑单个维度的变化:

x_i = closep[i:i+WINDOW]
y_i = closep[i+WINDOW+FORECAST]
last_close = x_i[-1]
    next_close = y_i
if last_close < next_close:
    y_i = [1, 0]
else:
    y_i = [0, 1]

所以,我们训练数据,和之前一样,是30天时间窗口,但是现在我们用每天整个OHLCV数据归一化来预测收盘价的变动方向。

神经网络框架

正如前面提到的,想用CNN做一个分类器。选它的主要原因是超参数的灵活性和可解释性(卷积内核,下采样大小等),以及类似于RNN的性能,比MLP训练更快。

代码如下:

model = Sequential()
model.add(Convolution1D(input_shape = (WINDOW, EMB_SIZE),
                        nb_filter=16,
                        filter_length=4,
                        border_mode='same'))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dropout(0.5))
model.add(Convolution1D(nb_filter=8,
                        filter_length=4,
                        border_mode='same'))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(64))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dense(2))
model.add(Activation('softmax'))

和第一篇文章的构架唯一不同的是在我们的案例中把EMB_SIZE变量改为5。

训练过程

让我们编译模型

opt = Nadam(lr=0.002)
reduce_lr = ReduceLROnPlateau(monitor='val_acc', factor=0.9, patience=30, min_lr=0.000001, verbose=1)
checkpointer = ModelCheckpoint(filepath="model.hdf5", verbose=1, save_best_only=True)
model.compile(optimizer=opt, 
              loss='categorical_crossentropy',
              metrics=['accuracy'])
history = model.fit(X_train, Y_train, 
          nb_epoch = 100, 
          batch_size = 128, 
          verbose=1, 
          validation_data=(X_test, Y_test),
          callbacks=[reduce_lr, checkpointer],
          shuffle=True)

并检查性能:

Loss after 100 epochs

Accuracy of binary classification after 100 epochs

从图中我们可以清楚地看到网络训练充分(对于非常嘈杂的数据),训练集损失随着时间下降,而精确度上升。最重要的是,相对于第一篇文章中的单变量时间序列,我们把准确度性能从58%提高到近65%。

为了检查过拟合,我们也绘制了混淆矩阵:

from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
model.load_weights("model.hdf5")
pred = model.predict(np.array(X_test))
C = confusion_matrix([np.argmax(y) for y in Y_test], [np.argmax(y) for y in pred])
print C / C.astype(np.float).sum(axis=1)

得到:

[[ 0.75510204  0.24489796]
[ 0.46938776  0.53061224]]

以上显示,我们预测向上幅度有75%的准确率,向下幅度有53%的准确率,当然这个结果和测试数据集差不多。

回归如何?

我们可以预测实际价值,即第二天的回报或收盘价,而不是预测二元变量。在我们之前的实验中,我们没有成功地产生好的结果。

不幸的是,在盈利上效果仍然不好:

回归问题的损失减少

价格变动的预测

预测收盘价不太好

预测收盘价

总结

我们讨论了多元时间序列中数据准备和归一化的一般流程,对它们进行CNN训练,我们取得了分类问题的显著改进(7%),是对股票在第二天上涨还是下跌的分类问题。

与此同时,我们仍然要说明回归问题对我们来说仍然过于复杂,我们会在稍后的工作中,选择正确的损失指标和激活函数。

明天的文章中,我们会介绍多模式学习的概念。尽请期待!

本文分享自微信公众号 - 量化投资与机器学习(Lhtz_Jqxx)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-02-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 放弃幻想,全面拥抱Transformer:自然语言处理三大特征抽取器(CNN/RNN/TF)比较

    在辞旧迎新的时刻,大家都在忙着回顾过去一年的成绩(或者在灶台前含泪数锅),并对2019做着规划,当然也有不少朋友执行力和工作效率比较高,直接把2018年初...

    beyondGuo
  • Random Forest

    随机森林还是没有脱离聚合模型这块,之前学过两个aggregation model,bagging和decision tree,一个是边learning边unif...

    西红柿炒鸡蛋
  • 分隔百度百科中的名人信息与非名人信息

    像错误提示说的那样需要的是字节类型而不是字符串类型,需要注意一下的是bytes-like翻译为字节。

    明天依旧可好
  • 机器学习第3天:多元线性回归

    简单线性回归:影响Y的因素唯一,只有一个。 多元线性回归:影响Y的因数不唯一,有多个。

    明天依旧可好
  • 第一章(1.2) 机器学习算法工程师技能树

    - 单机开发工具(numpy、sk-learn、pandas、libsvm、xgboost)

    两只橙
  • Learning ROS for Robotics Programming Second Edition学习笔记(一) indigo v-rep

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865

    zhangrelay
  • 基于Keras的DCGAN实现

    生成对抗网络(Generative Adversarial Network,简称GAN)是非监督式学习的一种方法,通过让两个神经网络相互博弈的方式进行学习。

    TheOneGIS
  • 大数据工程师需要学习哪些必备知识和技能呢?

    大数据这个行业在科学发展的潮流中也变得越来越火了,来带你看看大数据工程师需要学习哪些必备知识和技能呢?

    用户2292346
  • k-近邻算法

    从今天开始,与大家分享我学习《Machine Learning In Action》这本书的笔记与心得。我会将源码加以详细的注释,这是我自己学习的一个过程,也是...

    TheOneGIS
  • Finale

    这几篇博客介绍的第一个feature transform方法就是kernel。kernel先出现是在SVM里面,原因就是为了减少 內积计算的复杂度,把特征转换和...

    西红柿炒鸡蛋

扫码关注云+社区

领取腾讯云代金券