用CNN算法实现A股股票选股
由clearyf创建,最终由clearyf 被浏览 678 用户
导语
在阅读了 深度学习的简要介绍后,本文将介绍深度学习CNN模型及其在量化投资领域中的应用。
深度学习在量化领域应用
机器学习作为人工智能的核心,其传统算法在解决很多问题上都表现出了高效性。随着近些年数据处理技术上的进步和计算能力的提升,深度学习得以在很多问题上也大放光彩,成为近一段时间互联网、金融等领域的大热门。
在量化投资领域,机器学习尤其是由统计学延伸的各种算法一直以来都被尝试应用在选股、择时等策略的开发上,随着深度学习在其他领域上的突破,其在自动化交易甚至投资策略的自开发自学习方面的应用成为了大家探索的焦点。
为什么要用深度学习?
深度学习目前最成功的场景应用是在模式识别上,即利用已知数据,对具有一定空间、时间分布信息的数据与类别标号之间的映射做一个较好的估计。之所以在结构性识别的任务中,深度学习可以表现得比传统机器学习算法更好,主要有以下三点原因:
- 深度学习的自动提取特征比传统机器学习的人为提取特征过程更加高效。特定的应用场景中,只需要微调结构,如神经元的激活函数,就可以得到较好的效果。
- 深度学习可以通过复杂的结构和多重非线性处理层更好的捕捉各类非线性关系。
- 深度学习随着数据量的增加模型效果会不断的改善,这也是当前深度学习有逐渐取代传 统机器学习模型趋势的最大原因。
如何实现深度学习算法?
我们以CNN为例子,在本文末尾可克隆策略供各位研究。
策略缩略图如下: 第一步:通过证券代码列表模块设置股票池 第二步:通过输入特征列表模块构建需要参与训练的因子 第三步:通过特征抽取模块获取因子数据 第四步:通过数据过滤模块将因子数据划分为训练集和预测集 第五步:设定序列窗口滚动,将数据变换为窗口大小的数据序列。例如对于一维数据[1,2,3,4,5]如果设置滚动窗口大小为3,则变换为[ [1,2,3],[2,3,4],[3,4,5] ] 第六步:构建深度学习模型 第七步:模型训练 第八步:预测 第九步:回测
接下来我们着重讲解构建模型部分
构建深度学习模型
深度学习模型是由多个单层模型组合而成,通常划分为输入层、中间层和输出层。 我们可以通过可视化界面左侧的模块导航树中查看到可用的深度学习模块,如下图所示:
深度学习模型模块列表
各模块的说明可以参考文档 我们着重介绍本例中使用的模块:
全连接层(Dense)
全连接层中,所有输入层的节点一定和输出层的任一节点相连接。
- 每条连线对应了一个权重,令这些权值构成的矩阵为kernel权值矩阵。
- 通过使用偏置向量bias可以避免得出局部最优(只在 use_bias 为 True 时才有用)。
- activation 是按逐个元素计算的激活函数 Dense 将实现以下操作: output = activation(dot(input, kernel) + bias)
a. 模块位置 : b. 参数列表:
c. 参数解读:
权值初始化 多层网络初始化w的时候,一般不初始化为0,会初始化为一个非0的很小的参数。 w初始值不宜太大,若w初始过大,z值过大,dz值过小,学习会很慢(对于激活函数为sigmoid或tanh函数而言)
常量初始化(constant)
把权值或者偏置初始化为一个常数,具体是什么常数,可以自己定义
高斯分布初始化(gaussian)
需要给定高斯函数的均值与标准差
positive_unitball初始化
让每一个神经元的输入的权值和为 1,例如:一个神经元有100个输入,让这100个输入的权值和为1. 首先给这100个权值赋值为在(0,1)之间的均匀分布,然后,每一个权值再除以它们的和就可以啦。这么做,可以有助于防止权值初始化过大,从而防止激活函数(sigmoid函数)进入饱和区。所以,它应该比较适合sigmoid形的激活函数
均匀分布初始化(uniform)
将权值与偏置进行均匀分布的初始化,用min 与 max 来控制它们的的上下限,默认为(0,1)
xavier初始化
对于权值的分布:均值为0,方差为(1 / 输入的个数) 的 均匀分布。如果我们更注重前向传播的话,我们可以选择 fan_in,即正向传播的输入个数;如果更注重后向传播的话,我们选择 fan_out, 因为在反向传播的时候,fan_out就是神经元的输入个数;如果两者都考虑的话,就选 average = (fan_in + fan_out) /2。
msra初始化
对于权值的分布:基于均值为0,方差为( 2/输入的个数)的高斯分布;它特别适合 ReLU激活函数,该方法主要是基于Relu函数提出的。
d.偏置向量 :
目的是更好地拟合数据,具体效果可参考神经网络中偏置的作用
e. 激活函数的选择:
用于分类器时,Sigmoid函数及其组合通常效果更好。
由于梯度消失问题,有时要避免使用sigmoid和tanh函数。
ReLU函数是一个通用的激活函数,在大多数情况下广泛使用。
如果神经网络中出现死神经元,那么PReLU函数就是最好的选择。
请记住,ReLU函数只能在隐藏层中使用。
f. 输出空间维度:
决定输出层数据的维度。过大容易造成过拟合、运算时间长。过小容易造成欠拟合
Dropout层
Dropout 包括在训练中每次更新时, 将输入单元的按比率随机设置为 0, 这有助于防止过拟合。
a. 模块位置
b. 参数列表 :
c. 参数解读:
随机种子:
计算机并不能产生真正的随机数,如果你不设种子,计算机会用系统时钟来作为种子,如果你要模拟什么的话,每次的随机数都是不一样的,这样就不方便你研究,如果你事先设置了种子,这样每次的随机数都是一样的,便于重现你的研究,也便于其他人检验你的分析结果。
rate:在 0 和 1 之间浮动。需要丢弃的输入比例。适当丢弃数据可以有效防止过拟合。
输入层
a. 模块位置
b. 参数列表
c. 参数解读:
dtype:
输入所期望的数据类型,字符串表示 (float32, float64, int32...) 一个尺寸元组(整数),不包含批量大小。shape:
tuple (integer), not including the batch size. 例如,shape=(32,) 表明期望的输入是按批次的 32 维向量。本模板策略中输入特征有59个,所以此处输入的shape为59
batch_shape:
一个尺寸元组(整数),包含批量大小。 例如,batch_shape=(10, 32) 表明期望的输入是 10 个 32 维向量。 batch_shape=(None, 32) 表明任意批次大小的 32 维向量。
STM层
长短期记忆网络层
a. 模块位置
b. 参数列表
c. 参数解读:(激活函数等参数同上)
激活函数 :用于循环时间步的激活函数(详情见激活函数。
循环核初始化方法: 运用到 recurrent_kernel 权值矩阵的约束函数(详情见权值初始化。
Reshape层
将输入重新调整为特定的尺寸。
a. 模块位置:
b. 参数列表:
c. 参数解读:
target_shape: 目标尺寸。整数元组。 不包含表示批量的轴。
Conv2D层
该层创建了一个卷积核, 该卷积核对层输入进行卷积, 以生成输出张量,此模块是CNN模型的核心关键。
a. 模块位置
b.参数列表
**c. 参数解读:**激活函数等参数同上
卷积核数目: 输出空间的维度 (即卷积中滤波器的输出数量)。
kernel_size: 一个整数,或者 2 个整数表示的元组或列表, 指明 2D 卷积窗口的宽度和高度。 可以是一个整数,为所有空间维度指定相同的值。
步长: 一个整数,或者 2 个整数表示的元组或列表, 指明卷积沿宽度和高度方向的步长。 可以是一个整数,为所有空间维度指定相同的值。
dilation_rate: 一个整数或 2 个整数的元组或列表, 指定膨胀卷积的膨胀率。 可以是一个整数,为所有空间维度指定相同的值。 当前,指定任何 dilation_rate 值 != 1 与 指定 stride 值 != 1 两者不兼容。
模型组合连接
我们将各层模型组合连接,将输入和最终输出层连接到模型构建模块完成模型构建。
本例中我们将输入经过Reshape层变换为卷积层识别的三维数据,然后通过Conv2D将数据卷积化降维,再通过reshape层变换为LSTM层的输入,通过加入Dropout层来防止过拟合,最终通过一个全连接层输出一维标量数据(即涨跌预测概率)。
策略案例
完整的可视化案例策略如下:
https://bigquant.com/experimentshare/afb5223b656441bd83ba700fd13954b8
https://bigquant.com/experimentshare/b7056c04acf24e1b99eb3441187806ab
\