【python量化】用时间卷积神经网络(TCN)进行股价预测

2023-05-16

写在前面

下面这篇文章首先主要简单介绍了目前较为先进的时间序列预测方法——时间卷积神经网络(TCN)的基本原理,然后基于TCN的开源代码,手把手教你如何通过时间卷积神经网络来进行股价预测,感兴趣的读者也可以基于此模型来用于自己的数据集的训练和预测。

1

TCN的基本原理与结构

TCN全称Temporal Convolutional Network,时序卷积网络,是在2018年提出的一个模型,可以用于时序数据处理。卷积网络已被证明在提取结构化数据中的高级特征方面具有不错的效果。而时间卷积网络则是一种利用因果卷积空洞卷积的神经网络模型,它可以适应时序数据的时序性并可以提供视野域用于时序建模。

1、因果卷积

训练时间卷积网络预测输入时间序列的下  个值时,假设输入序列为  ,希望预测一些相应的输出  ,它的值等于输入值向前移动  个单位。在进行预测的时候主要的限制是,当预测某个时间步长t的输出  时,它只能使用前面观察到的输入  。

因此,TCN有两个主要约束:网络的输出应该与其输入具有相同的长度,并且网络只能使用过去时间步长的信息。为了满足这些时间性原则,TCN中使用了一个1维全卷积网络结构,即它的所有卷积层具有相同的长度,并带有零填充,以确保更高的层与之前的层相同的长度。此外,TCN使用因果卷积,即每一层的时间步长t的输出只计算不晚于前一层时间步长t的区域,如下图所示。对于一维数据,通过将常规卷积的输出移动几个时间步长,可以很容易地实现因果卷积。

2、空洞卷积

一般来说,在处理时间序列时,人们期望网络能够记住长期信息。然而,在我们前面展示的因果卷积中,除非叠加很多层,否则接收域的大小是有限的。因此,为了克服这些问题,这里使用了空洞卷积来实现有限层网络具有指数级别大小的接收域。空洞卷积是一种卷积,通过跳过给定步骤的大小,然后在一个比它的大小更大的区域上应用滤波器。这类似于池化或跨步卷积,因为它增强了接收区域的大小,但它使输出大小等于输入。当使用空洞卷积时,通常会随着网络的深度指数增加空洞夸张因子d。这保证了历史记录中每个输入的接收域,并通过使用深度网络获得一个非常大的接收域作为有效的历史记录。下图是一个因果空洞卷积的图示。

3、残差连接

由于TCN的接收域大小取决于网络深度n、滤波器大小k和空洞扩张因子d,因此使TCN变深变大是获得足够大的接收域的关键。从经验上看,使网络变深变窄,即叠加大量的层,选择较细尺度的过滤器尺寸,是一种有效的架构。残差连接已被证明是非常有效的训练深度网络。在残差网络中,整个网络采用跳跃连接,以加快训练过程,避免深度模型的梯度消失问题。

2

基于TCN进行股价预测

下面将介绍一个基于TCN进行股价预测的基本例子。用到的TCN模型的原理来自论文:An Empirical Evaluation of Generic Convolutional and Recurrent Networks for Sequence Modeling,TCN模型的代码来自github的开源代码:https://github.com/philipperemy/keras-tcn。

本地环境:

Python 3.7
IDE:Pycharm

库版本:

pandas  1.0.3
numpy  1.18.1
matplotlib  3.2.1
tensorflow  2.3.1
sklean  0.22.2

1、数据预处理以及数据集的划分

为了便于演示,数据用到了上证指数从2005到2018年的日线数据,感兴趣的读者也可以将其更换为自己本地的数据。首先,需要导入需要的相关模块,其中tcn模块来自上面的github链接中代码的tcn模块:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from tcn.tcn import TCN
from tensorflow import keras

接下来需要定义几个全局变量:

window_size = 10   # 窗口大小
batch_size = 32    # 训练批次大小
epochs = 200       # 训练epoch
filter_nums = 10   # filter数量
kernel_size = 4    # kernel大小

然后,我们通过定义一个函数来读取数据并划分训练集和测试集,其中首先需要读取数据并对数据进行归一化处理,以便于模型的训练,这里以上证指数的开盘价为例。然后,通过滑动窗口的形式对数据进行划分,最后,划分后的数据前2000条作为训练集,后1000条数据作为测试集。具体代码如下所示:

def get_dataset():
    df = pd.read_csv('./000001_Daily_2006_2018.csv')
    scaler = MinMaxScaler()
    open_arr = scaler.fit_transform(df['Open'].values.reshape(-1, 1)).reshape(-1)
    X = np.zeros(shape=(len(open_arr) - window_size, window_size))
    label = np.zeros(shape=(len(open_arr) - window_size))
    for i in range(len(open_arr) - window_size):
        X[i, :] = open_arr[i:i+window_size]
        label[i] = open_arr[i+window_size]
    train_X = X[:2000, :]
    train_label = label[:2000]
    test_X = X[2000:3000, :]
    test_label = label[2000:3000]
    return train_X, train_label, test_X, test_label, scaler

2、模型的构建

模型的构建用到了keras,其中模型的输入层需要按照TCN层的指定形式,window_size表示窗口的大小,即输入数据的长度,1表示每个时间点的维度。之后的TCN层中,每个参数的含义如下所示:

  • nb_filters: 整数。在卷积层中使用的filter的数量。将类似于LSTM层中的units。

  • kernel_size: 整数。在每个卷积层中使用的kernel的大小。

  • dilation: 列表。表示每层中使用的空洞因子的大小的列表。例如:[1, 2, 4, 8, 16, 32, 64]。

  • nb_stacks: 整数。要使用残差块的堆栈数量。

  • padding: 字符串。在卷积中使用的填充。在因果网络中使用“causal”,而在非因果网络中使用“same”。

  • use_skip_connections: 布尔。如果我们想要添加从输入到每个残差块的skip connection。

  • return_sequences: 布尔。是返回输出序列中的最后一个输出,还是返回完整序列。

  • dropout_rate: 浮动在0和1之间。要dropout的比重。

  • activation: 使用的激活函数。

  • kernel_initializer: kernel权值矩阵(Conv1D)的初始化器。

  • use_batch_norm: 是否在使用批处理规范化。

  • kwargs: 用于配置父类层的任何其他参数。

在完成了TCN层的设置之后,后面接一层一个输出的全连接层进行输出最后的预测结果,其中用到的激活函数是relu。最后对模型进行编译以及训练,训练的loss是mae,优化器是adam。

def build_model():
    train_X, train_label, test_X, test_label, scaler = get_dataset()
    model = keras.models.Sequential([
        keras.layers.Input(shape=(window_size, 1)),
        TCN(nb_filters=filter_nums,                   
            kernel_size=kernel_size,                   
            dilations=[1, 2, 4, 8]),     
        keras.layers.Dense(units=1, activation='relu')
    ])
    model.summary()
    model.compile(optimizer='adam', loss='mae', metrics=['mae'])
    model.fit(train_X, train_label, validation_split=0.2, epochs=epochs)

最后对模型进行评估,对预测结果进行反归一化并进行可视化:

    model.evaluate(test_X, test_label)
    prediction = model.predict(test_X)
    scaled_prediction = scaler.inverse_transform(prediction.reshape(-1, 1)).reshape(-1)
    scaled_test_label = scaler.inverse_transform(test_label.reshape(-1, 1)).reshape(-1)
    print('RMSE ', RMSE(scaled_prediction, scaled_test_label))
    plot(scaled_prediction, scaled_test_label)

模型的结构以及训练过程如下所示:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
tcn (TCN)                    (None, 10)                2940      
_________________________________________________________________
dense (Dense)                (None, 1)                 11        
=================================================================
Total params: 2,951
Trainable params: 2,951
Non-trainable params: 0
_________________________________________________________________
Epoch 1/200
50/50 [==============================] - 1s 14ms/step - loss: 0.0739 - mae: 0.0739 - val_loss: 0.0131 - val_mae: 0.0131
Epoch 2/200
50/50 [==============================] - 0s 5ms/step - loss: 0.0141 - mae: 0.0141 - val_loss: 0.0063 - val_mae: 0.0063
Epoch 3/200
50/50 [==============================] - 0s 7ms/step - loss: 0.0130 - mae: 0.0130 - val_loss: 0.0048 - val_mae: 0.0048
Epoch 4/200
50/50 [==============================] - 0s 6ms/step - loss: 0.0115 - mae: 0.0115 - val_loss: 0.0081 - val_mae: 0.0081
Epoch 5/200
50/50 [==============================] - 0s 6ms/step - loss: 0.0130 - mae: 0.0130 - val_loss: 0.0052 - val_mae: 0.0052
Epoch 6/200
50/50 [==============================] - 0s 6ms/step - loss: 0.0122 - mae: 0.0122 - val_loss: 0.0046 - val_mae: 0.0046
Epoch 7/200
50/50 [==============================] - 0s 6ms/step - loss: 0.0109 - mae: 0.0109 - val_loss: 0.0058 - val_mae: 0.0058
Epoch 8/200
50/50 [==============================] - 0s 6ms/step - loss: 0.0116 - mae: 0.0116 - val_loss: 0.0063 - val_mae: 0.0063
Epoch 9/200
50/50 [==============================] - 0s 6ms/step - loss: 0.0111 - mae: 0.0111 - val_loss: 0.0062 - val_mae: 0.0062
Epoch 10/200
50/50 [==============================] - 0s 5ms/step - loss: 0.0112 - mae: 0.0112 - val_loss: 0.0056 - val_mae: 0.0056

模型训练完之后,打印的RMSE如下所示:

RMSE  35.78251267773438

预测的效果如下图所示,可以看到模型的拟合效果还可以,基本拟合出了价格的基本走势。

完整代码如下所示:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from tcn.tcn import TCN
from tensorflow import keras


window_size = 10   # 窗口大小
batch_size = 32    # 训练批次大小
epochs = 200       # 训练epoch
filter_nums = 10   # filter数量
kernel_size = 4    # kernel大小




def get_dataset():
    df = pd.read_csv('./000001_Daily_2006_2018.csv')
    scaler = MinMaxScaler()
    open_arr = scaler.fit_transform(df['Open'].values.reshape(-1, 1)).reshape(-1)
    X = np.zeros(shape=(len(open_arr) - window_size, window_size))
    label = np.zeros(shape=(len(open_arr) - window_size))
    for i in range(len(open_arr) - window_size):
        X[i, :] = open_arr[i:i+window_size]
        label[i] = open_arr[i+window_size]
    train_X = X[:2000, :]
    train_label = label[:2000]
    test_X = X[2000:3000, :]
    test_label = label[2000:3000]
    return train_X, train_label, test_X, test_label, scaler


def RMSE(pred, true):
    return np.sqrt(np.mean(np.square(pred - true)))


def plot(pred, true):
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(range(len(pred)), pred)
    ax.plot(range(len(true)), true)
    plt.show()


def build_model():
    train_X, train_label, test_X, test_label, scaler = get_dataset()
    model = keras.models.Sequential([
        keras.layers.Input(shape=(window_size, 1)),
        TCN(nb_filters=filter_nums,                   # 滤波器的个数,类比于units
            kernel_size=kernel_size,                   # 卷积核的大小
            dilations=[1, 2, 4, 8]),     # 空洞因子
        keras.layers.Dense(units=1, activation='relu')
    ])
    model.summary()
    model.compile(optimizer='adam', loss='mae', metrics=['mae'])
    model.fit(train_X, train_label, validation_split=0.2, epochs=epochs)


    model.evaluate(test_X, test_label)
    prediction = model.predict(test_X)
    scaled_prediction = scaler.inverse_transform(prediction.reshape(-1, 1)).reshape(-1)
    scaled_test_label = scaler.inverse_transform(test_label.reshape(-1, 1)).reshape(-1)
    print('RMSE ', RMSE(scaled_prediction, scaled_test_label))
    plot(scaled_prediction, scaled_test_label)


if __name__ == '__main__':
    build_model()


4

总结

在这篇文章中,我们首先简单介绍了时间卷积网络的一些基本内容,然后基于开源的时间卷积网络的代码,实现了一个简单的例子,将其应用于上证指数价格的预测当中。从结果中可以看出,时间卷积网络具有很强的数据拟合能力和时序建模能力。当在将其应用于股价预测当中时,仍不可避免地面临过拟合、模式迁移以及市场噪声的影响。即便如此,在RNN、LSTM占据时序处理领域的情况下,TCN作为一种新颖的技术仍具有很强的研究意义与价值。

了解更多人工智能与
量化金融知识

<-请扫码关注

让我知道你在看

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【python量化】用时间卷积神经网络(TCN)进行股价预测 的相关文章

  • L4Linux的版本比较

  • 利用XML文件的一个写日志的类!!!!!

    对于程序执行期间的错误跟踪 xff01 相信大家都有自己的一套办法 xff01 xff01 xff01 但都是利用文件文件 xff0c 我这次利用的是XML amp XSL xff0c 可产生报表格式的日志 轻松生成报表 xff01 xff
  • 【Kubernetes实战】(四)MiniKube方式部署

    目录 一 当前配置环境 二 准备工作 1 关闭防火墙和SeLinux 2 禁用swap交换分区 三 Docker安装 1 配置docker源 2 安装docker环境依赖 3 安装docker 4 启动docker并设置为开机自启 5 配置
  • DGPS与RTK的区别

    2013 10 11 10 49 11 分类 xff1a GNSS 举报 字号 订阅 最近一直感觉身在这个行业不能对这个行业理论知识一无所知 xff0c 这对于技术人来说应该是一种遗憾 所以决定要学一些东西 xff0c 并记录下来以便于以后
  • 基于Ubuntu19.04安装docker

    输入命令 lsb release a 显示如下 Distributor ID Ubuntu 类别是ubuntu Description Ubuntu 19 04 16年3月发布的稳定版本 xff0c LTS是Long Release 19
  • PHP获取当月开始时间和结束时间

    startTime 61 date 39 Y m 01 39 time 获取该月份的第一天 endTime 61 date 39 Y m t 39 time 获取该月份的最后一天
  • CSS3实现动态进度条

    CSS3的线性渐变使制造动态进度条成为可能 现在就来一步一步讲解如何创建动态进度条吧 以Chrome浏览器webkit内核为例 目标 xff1a 单个矩形条背景 目标进度条 xff0c 背景是淡蓝色 xff0c 上面平铺了一层倾斜的深蓝色条
  • C语言-阶乘数列

    求Sn 61 1 43 2 43 3 43 4 43 5 43 43 n 之值 xff0c 其中n是一个数字 include lt stdio h gt include lt math h gt long long factorial in
  • 深入MTK平台bootloader启动之【 Pre-loader -> Lk】分析笔记

    1 bootloader到kernel启动总逻辑流程图 ARM架构中 xff0c EL0 EL1是必须实现 xff0c EL2 EL3是选配 xff0c ELx跟层级对应关系 xff1a EL0 app EL1 Linux kernel l
  • STM32输出模式详解

    本文为个人见解 xff0c 如有问题欢迎指正 首先需要明确输出 输入的意思 输出是指STM32控制外设 xff08 主要指输出高电平或低电平 xff09 或STM32发送数据给外设 xff0c 输入是指外设发送数据给STM32 输出模式有三
  • [OPNET学习总结]——SITL

    软件自带的SITL例程中 xff0c 出现如下error xff1a lt lt lt Recoverable Error gt gt gt Object repository construction failed due to erro
  • 漫谈程序员系列:程序员的生活就这样吗

    我当了快十年程序员了 xff0c 终于老得可以来谈谈程序员的生活是什么样子了 或许陈奕迅的 十年 中的一段歌词 xff0c 可以表示很多程序员和软件开发之间的感情纠葛 xff1a 十年之前 我不认识你 你不属于我 我们还是一样 陪在一个陌生
  • 程序员转行为什么这么难

    尽管我在 大龄程序员的未来在何方 这篇文章里比较乐观地介绍了程序员保持竞争力的几个方向 xff0c 但现实依然是残酷的 xff1a 很多人将不得不离开软件开发工作 xff0c 转型去从事其他职业 当你要这么做时 xff0c 就会感慨 xff
  • 使用http_parser解析URL

    用C语言编写http应用 xff0c 解析URL是一个繁琐的事儿 前几天使用http parser实现httpclient xff0c 发现里面提供了一个解析URL的方法http parser parse url xff0c 用起来相当方便
  • Android app 后台被杀恢复

    android 模拟应用因内存不足被后台杀死命令 https www jianshu com p effb4546b9aa adb shell am kill all 应用通过home键已经停留在后台使用 xff0c 杀掉所有后台程序 xf
  • Ubuntu查看linux系统版本号

    查看ubuntu版本 输入命令 cat proc version 显示如下 Linux version 5 0 0 13 generic buildd 64 lcy01 amd64 020 linux内核版本号 gcc version 8
  • Linux C Socket简介和实现

    1 网络中进程之间如何通信 xff1f 本地的进程间通信 xff08 IPC xff09 有很多种方式 xff0c 但可以总结为下面4类 xff1a 消息传递 xff08 管道 FIFO 消息队列 xff09 同步 xff08 互斥量 条件
  • C++ STL视频教程,初学者必备视频资料

    STL视频教程 初学者必备视频资料 我一个朋友做的 我转发到这里和大家分享 STL语音视频教程 下载地址 xff1a url 61 http www ctdisk com file 3388918 STL语音视频教程 7z url
  • QMessageBox简单用法(QT5.12)

    span class token comment for starf study span span class token macro property span class token directive hash span span
  • TOF相机 Realsense L515 与 Ipad pro Lidar Camera 对比

    最近好奇都是TOF 相机 L5151 和 Ipad pro 上带的深度相机模块有啥不一样 网上很少有相关的中文资料来介绍 原理上的差异 简单搜索了一下 在此小小总结 Apple Lidar Camera 苹果采用的激光是 VCSEL Ver

随机推荐

  • Arduino 读取GPS 数据发送解析并发布ROS topic(一)

    概述 通过Arduino收集GPS数据 xff0c 连接至电脑端 xff0c 在电脑端通过python对数据进行整理 xff0c 并通过发布 TOPIC xff0c 本部分主要记录如何通过Arduino读取GPS数据 接线方式 GPS 的
  • STM32 复位电路设计

    在此之前我是个只会抄写原理图的工程师 xff0c 每当遇到一个问题时 xff0c 确需要解决很久 xff0c 最根本的原因在于不明白其中的原理 xff0c 这次补充一下单片机复位电路设计 1 为什么要设计复位电路 xff1f 在做一件事情之
  • STM32核心板设计——电源设计

    1 STM32 数据手册电源部分研读 RTC电源管脚为V BAT 电源范围为1 8 3 6V xff0c 主要用于RTC时钟的供电 xff0c RTC在大部分场合用于保存一些重要的参数 xff0c 比如在电脑主板上用于保存boss的信息 x
  • stm32的复位电路问题

    现在比较流行的复位方式是这样的 xff1a 但我们都知道对于结构紧凑型硬件来说 xff0c 多一个电阻都是没必要的 在没有手动复位需求的场合 xff0c 能不能删掉按键与R24 xff0c 仅保留104电容 xff1f 通过阅读stm32
  • 外设驱动库开发笔记21:BME680环境传感器驱动

    环境传感器是一类我们很常用的传感器 它可以方便我们获取压力 温度 湿度以及空气质量等数据 在这一篇中 xff0c 我们将分析 BME680 环境传感器的功能 xff0c 并设计和实现 BME680 环境传感器的驱动 1 功能概述 BME68
  • 外设驱动库开发笔记45:MS4515DO压力传感器驱动

    很多时候我们需要检测流量和压力这些参数 xff0c 比如我们要检测大气压 xff0c 或者通过测量差压来获得输送流体的流量等 xff0c 都需要用到压力传感器 这一篇我们就来讨论MS4515DO压力传感器的数据获取 1 功能概述 MS451
  • 一个好看的CSS样式表格

    一个好看的CSS样式表格 自动换整行颜色的CSS样式表格 xff08 需要用到JS xff09 自动换整行颜色的CSS样式表格源代码 自动换整行颜色的CSS样式表格 xff08 需要用到JS xff09 这个CSS表格会自动切换每一行的颜色
  • docker删除镜像

    docker要删除镜像 xff0c 先要删除依赖它的容器 1 删除容器 docker ps 查看正在运行的容器 docker ps a 查看所有容器 docker rm container id 删除容器 2 删除镜像 docker ima
  • FreeRTOS如何结束和重新启动调度程序

    大多数主机或桌面系统 xff08 比如Linux xff0c Mac或Windows xff09 都有一个正常的用例 xff0c 你可以在早上启动操作系统 xff0c 然后在晚上关闭它 xff0c 然后你就离开机器 嵌入式系统是不同的 xf
  • [显存被占满,程序无法运行问题]ResourceExhaustedError (see above for traceback): OOM when allocating tensor

    最近在实验室的服务器上跑tensorflow程序 xff0c 一直都没有报错 xff0c 但是今天却突然报错 xff0c 而且出错提示显示的内容从未见到过 xff0c 错误提示如下 xff1a 错误提示资源耗尽 xff0c 无法分配tens
  • 解读神经网络十大误解,再也不会弄错它的工作原理(转载自机器之心)

    神经网络是机器学习算法中最流行和最强大的一类 在计量金融中 xff0c 神经网络常被用于时间序列预测 构建专用指标 算法交易 证券分类和信用风险建模 它们也被用于构建随机过程模型和价格衍生品 尽管神经网络有这些用处 xff0c 但它们却往往
  • 树莓派 Raspberry Pi VNC屏幕无法显示、软键盘、摄像头实时图传、固定IP等环境配置

    目录 1 VNC屏幕无法显示 2 树莓派软键盘安装 3 摄像头实时图传配置 xff0c 可用于图像监控系统 4 安装VIM与固定IP 1 VNC屏幕无法显示 在树莓派终端 xff0c 输入 sudo raspi config 选择接口配置
  • 在Jetson上配置RealSense相机驱动

    1 下载源码 https github com IntelRealSense librealsense span class token builtin class name cd span librealsense scripts set
  • aruco marker使用笔记

    在英伟达Jetson Xaiver开发板上配置 SDK环境 opencv 4 1 1 CUDA 10 2 1 git clone https github com pal robotics aruco ros 2 复制到catkin ws
  • catkin_make命令

    catkin make是在catkin工作区中构建代码的便捷工具 catkin make遵循catkin工作区的标准布局 xff0c 如REP 128中所述 用法 假设您的catkin工作区位于 catkin ws中 xff0c 则应始终在
  • docker容器中运行界面程序

    Docker比较常用的场景是 运行无界面的后台服务 或者 运行Web服务 不过有时出于个人的喜好或特定的需求 xff0c 我们会希望在Docker中运行带图形界面的应用程序 将容器中的图形界面展示到外部的一般性思路 xff1a 目前Unix
  • linux录屏

    Linux下好用的录屏软件是kazam录屏后视频处理软件kdenlive根据剪辑好的视频撰写解说词 xff0c 使用讯飞配音app将解说词文字转换为语音mp3将语音与视频通过kdenlive软件合成在一起 xff0c 完美的演示视频诞生了
  • 【python】conda和pip安装库之间的区别

    conda 首先 xff0c conda是一个通用的包管理器 xff0c 意思是什么语言的包都可以用其进行管理 xff0c 自然也就包括Python了 在安装Anaconda或者Miniconda时 xff0c 会对conda进行一同安装
  • OpenHarmony-Overview_zh

    OpenHarmony开源项目 项目介绍 OpenHarmony是开放原子开源基金会 xff08 OpenAtom Foundation xff09 旗下开源项目 xff0c 定位是一款面向全场景的开源分布式操作系统 OpenHarmony
  • 【python量化】用时间卷积神经网络(TCN)进行股价预测

    写在前面 下面这篇文章首先主要简单介绍了目前较为先进的时间序列预测方法 时间卷积神经网络 xff08 TCN xff09 的基本原理 xff0c 然后基于TCN的开源代码 xff0c 手把手教你如何通过时间卷积神经网络来进行股价预测 xff