跳转至

量化投资入门系列(九)——TabNet解析与使用

引言

在前面的文章中我们提到,神经网络与xgboost等决策树类的模型相比,更加适合处理日内的数据,因为日间数据更多的是结构化的数据,而神经网络更适合的是同质化的数据,其在表格数据的处理能力是不及xgboost的,但是神经网络毕竟是当前最为火热的机器学习方法,如果仅仅因为处理不好表格数据就放弃这一工具似乎有点对不起自己的显卡,而TabNet就是问题下的产物,其采用决策树的思路来构建神经网络,从而使得网络可以对表格化的数据有更好的处理能力。

神经网络模拟决策树结构

决策树的原理这里不做过多的赘述,其基本思想就是在特征上做划分,如图所示,对于一个二维的数据结构,决策树可以将其划分为四个区域,对于任意输入(x1, x2),可以通过与划分点a和d的关系来输出相应的类别。

决策树划分示例

TabNet的研究者提出了以下的结构来通过神经网络模拟决策树,按图中的二维的数据结构示例,对于输入(x1,x2),首先会经过Mask层,每个Mask节点中当前特征的值为1,而对于其他节点则为0,通过Mask层之后,每条通道就只剩下对应的特征的值,其他的特征均为0,从而达到了特征选择的效果,接下来通过一个全连接层, 其中W向量,对于相应特征对应的两个位置有互为相反数的两个值,b向量类似,设置为互为相反数的目的是配合ReLU来使用的,如果x1大于a,在向量的第一个值会通过ReLU而第二个值会变成0,从而实现类似于划分的效果。各个通道的值最终相加后通过Softmax函数来达到输出类别的效果。

TabNet详解

有了上面的基础,我们可以进一步来看TabNet的完整结构,整体的结构如下图所示,我们根据数据传递的方向来细看。

原始的特征,会分成两个数据流,第一个会直接进入Feature transformer的结构,目的是为第一个Step提供对应的Mask,而第二个数据流则是进入到所谓的决策树结构中。Feature transformer模块的结构如下,整体结构类似于ResNet的结构,在全连接层的传输过程中加入了一定残差的信息,比较特殊的是整个Feature transformer结构被分成了两个部分,左边的部分是参数共享,而右边的部分是每个Step独立的,这里我们结合后面的Split模块一起进行说明,Split模块的作用比较简单,就是将Feature transformer的输出按照参数是否共享来分成两个部分,左边共享参数的部分将用于传递个下一个Step作为Attentive transformer的输入,而右边各Step独立的部分则传递给本Step的ReLU函数。现在我们可以明白这里为什么要拆分两个部分,左边共享,是因为这部分的输出会向下传递,在整个网络的各个Step中都会产生影响,而右边独立的部分则只会对本Step的后续输出有影响,所以参数应该独立处理。

在经过Feature transformer并经Split之后,左边的部分会进入Attentive transformer结构来产生下一个Step的Mask,这里最终的会经过Sparsemax层,其作用是产生稀疏的向量结构,这与Mask的结构是相对应的。而右边的部分则会经过ReLU函数来产生本Step的输出,从而达到特征选择的效果。

tabnet-series-investment-entry-quantitat_22Apr28161225700257_1.jpeg

而在经过ReLU输出之后,数据在向下传输的同时,还是对自身做一次求和,这一步求和的作用我们可以理解为该Step对于整体的影响,而求和之后,还将与经过Mask之后的特征相乘,这就代表了本特征的影响,类似于决策树中某个特征的信息熵。

回到我们的问题,对于表格化的数据,TabNet为我们提供的相应的网络结构,该网络是以神经网络来模拟决策树的构建过程,每一个特征都得到了独立处理之后再与其他特征进行结合,从而避免了普通的多层感知机结构无法处理非同质化数据的过程,相对于决策树,TabNet由于内部的复杂性,其拟合能力相对于决策树更高。因此,针对于选股等更多依赖于表格化数据的问题,我们可以尝试来使用TabNet来进行处理,而更重要的是,TabNet的提出,使得量化过程中的因子挖掘与使用深度学习不再有天然的矛盾,我们可以像使用xgboost一样将大量高IC的特征使用到神经网络当中。

TabNet使用

目前TabNet针对Pytorch和tensorflow都提供了现成的包供使用,下面以Pytorch为例介绍使用:

安装上可以直接pip安装 pip install pytorch-tabnet

使用上与sklearn中各个模型的方法很相似:

1
2
3
4
5
6
7
8
from pytorch_tabnet.tab_model import TabNetClassifier, TabNetRegressor

clf = TabNetClassifier()  #TabNetRegressor()
clf.fit(
  X_train, Y_train,
  eval_set=[(X_valid, y_valid)]
)
preds = clf.predict(X_test)

其中模型以及训练的详细参数可以参考官方文档

凡本网注明"来源:XXX "的文/图/视频等稿件,本网转载出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性。如涉及作品内容、版权和其它问题,请与本网联系,我们将在第一时间删除内容!
作者: 李浩然, 华泰证券 算法工程师
来源: https://zhuanlan.zhihu.com/p/437645570