NODE:处理表格数据的前沿深度学习算法
深度学习在计算机视觉、自然语言处理、强化学习等领域引发了革命。然而,表格数据领域仍然主要由经典机器学习算法(尤其是梯度提升算法)主导。
直觉上,这很奇怪,不是吗?神经网络是通用逼近器,理想情况下它们应该也能逼近表格数据领域的函数。或许它们可以,但需要海量数据才能正确学习该函数?但梯度提升树为何能表现得如此出色?可能是决策树的归纳偏置非常适合表格数据领域?
既然它们这么好,为什么不在神经网络中使用决策树呢?就像我们为图像使用卷积操作,为文本使用循环网络一样,为什么不能将决策树作为表格数据的基本构建块?
答案很简单:树不可微,没有梯度流过网络,反向传播就会失效。但这正是研究人员开始攻坚的地方。我们如何使决策树可微?
可微决策树
2015年,Kontschieder等人提出了深度神经决策森林,它具有类似决策树的结构,但可微。
先回顾一下决策树。典型的决策树由决策节点和叶节点集合组成,共同作为一个函数。
先看叶节点,因为它更容易。在传统决策树中,叶节点通常是类标签上的分布。这正符合Sigmoid或Softmax激活函数的功能。因此可以用SoftMax层替换叶节点,使该节点可微。
现在深入探讨决策节点。决策节点的核心目的是决定将样本路由到左侧还是右侧。此决策使用特定特征和阈值——即该节点的参数。
在传统决策树中,此决策是二元决策;要么左要么右,0或1。但这是确定性的且不可微。如果放宽此限制,使路由变为随机性,会怎样?不再是严格的1或0,而是介于0和1之间的数字。这听起来很熟悉,不是吗?Sigmoid函数?
这正是Kontschieder等人提出的方法。如果通过Sigmoid函数将严格的0-1决策放宽为随机决策,节点就变得可微了。
现在知道单个节点(决策或叶节点)如何工作。将它们组合起来。图中的红色路径是决策树中的一条路径。在确定性版本中,样本要么经过这条路径,要么不经过。如果用概率术语思考相同的过程,样本要到达路径末端的叶节点,该路径中每个节点处样本走该路径的概率都应为1。
在概率范式中,计算样本向左或向右的概率,并将沿路径的所有这些概率相乘,得到样本到达该叶节点的概率。
样本到达高亮叶节点的概率为:路径上每个决策的概率乘积。
接着,只需使用每个决策路径的概率对所有叶节点取期望值,即可得到样本的预测。
理解了如何在神经网络中使用类决策树结构的原理后,来谈谈NODE模型。
神经遗忘树
遗忘树是对称生长的决策树。这类树在树的每一层使用相同的特征将学习实例分割成左右分区。CatBoost是一种著名的梯度提升实现,就使用遗忘树。遗忘树特别有趣,因为它们可以简化为具有2^depth个单元格的决策表,其中depth是树的深度。这非常简洁地简化了问题。
每个遗忘决策树输出2^depth个响应之一,其中depth是树的深度。这是通过使用depth个特征-阈值组合实现的,这些组合是ODT的参数。
形式上,ODT可以定义为:树输出由多个基于特征和阈值的阶跃函数组合决定。
为了使树的输出可微,应该用其连续对应物替换分裂特征选择和基于阈值的比较操作。
在传统树中,选择特征来分裂节点是确定性决策。但为了可微性,选择更柔和的方法,即特征的加权和,其中权重是学习得到的。通常,会考虑在特征上进行Softmax选择,但希望具有稀疏特征选择,即希望仅基于少数(最好是一个)特征做出决策。因此,NODE在可学习的特征选择矩阵上使用entmax变换。
类似地,将阶跃函数放宽为二类entmax。由于不同特征可能具有不同的特征尺度,使用参数τ对entmax进行缩放,其中μ和τ分别是可学习的阈值和尺度参数。
一个树有两边,通过上述操作只定义了一边。为了完成树,将一个树堆叠在另一个之上。现在将“选择”张量定义为所有树的外积:
这给出了选择权重,即每个响应张量输出的概率。现在问题简化为响应张量的加权和,由选择张量加权。
神经遗忘决策集成
从单个树到“森林”的跳跃非常简单。如果集成中有m棵树,最终输出是m个单独树输出的串联。
NODE的深层扩展
除了开发核心模块,他们还提出了深层版本,通过残差连接将多个NODE层堆叠在一起。输入特征和所有先前层的输出被连接起来,馈送到下一个NODE层,依此类推。最终,来自所有层的最终输出被平均。
训练与实验
数据处理:在论文的所有实验中,他们使用分位数变换将每个特征转换为服从正态分布。这一步对于稳定训练和更快收敛很重要。
初始化:在训练网络之前,他们提出进行数据感知初始化以获得良好的初始参数。特征选择矩阵均匀初始化,阈值用随机特征值初始化。尺度的初始化方式使得第一批中的所有样本都落在双侧entmax的线性区域,从而获得非零梯度。最终,响应张量使用标准正态分布初始化。
实验结果:该论文使用6个数据集进行实验——Epsilon、YearPrediction、Higgs、Microsoft、Yahoo和Click。他们将NODE与CatBoost、XGBoost和FCNN进行了比较。
首先,他们在所有算法上使用默认超参数进行比较。NODE的默认架构设置如下:2048棵深度为6的树的单层。这些参数继承自CatBoost默认参数。
然后,他们对所有算法进行了调优并进行了比较。
代码与实现
作者已在PyTorch中提供了一个即用模块的实现。FINISHED