集成学习之极限梯度提升

一 从集成学习说起

首先我们会有个疑问:什么是集成学习呢?通常的有监督机器学习任务可能就是做个分类或者回归,整个过程就是在学习一个函数,用于拟合训练数据。那相对应的,集成学习的目标就是通过多个函数,从而更好的拟合训练数据,达到更加精确的目的,所谓众人拾柴火焰高。

二 集成学习之流派

集成学习常见的分法可以分为Bagging和Boosting两大类。先说Bagging,代表方法是随机森林,这里每棵树的目标都是学习拟合目标数据,相当于随机森林就是同时学习多个决策树,并且最终的结果会考虑每棵树的影响,即如果是分类的目的,可以考虑把较多棵树的预测结果作为最终的类别;如果是回归的目的,可以考虑把所有树的结果求个平均。很明显,Bagging的目的并不是让其中某个单独的模型很强,而是想从整体合成的大模型上令最终的结果非常准,因此它想做的是:降低整体的方差。对于Boosting,比较经典的代表算法有:gbdt、xgb等模型。对于Boosting集成学习,它的思路是这样的:第一个模型尽量拟合训练数据,而第二个模型不去拟合原始的训练数据,而是拟合第一个模型在拟合训练数据时产出的误差,而后续所有的模型也是同理,都是拟合前一个模型的残差。因此Boosting实现是串行式的,这也是它与Bagging的本质区别。

三 XGB的原理与实现细节

1 公式推导

XGBoost和GBDT两者都是boosting方法,除了工程实现、解决问题上的一些差异外,最大的不同就是损失函数的定义。因此,我们从目标函数开始探究XGBoost的基本原理。
L = ∑ i n ( y ′ i , y i ) + ∑ k Ω ( f k ) L=\sum_{i}^n(y{'}_i,y_i)+\sum_{k}\Omega(f_k) L=in(yi,yi)+kΩ(fk)
其中,n为样本数量;k是树的个数, Ω ( f k ) \Omega(f_k) Ω(fk)是第k棵树的复杂度。

我们知道模型的预测精度由模型的偏差和方差共同决定,损失函数的前半部分代表了模型的偏差;想要方差小则需要在目标函数中添加正则项,用于防止过拟合。所以目标函数的后半部分是抑制模型复杂度的正则项 ,这也是XGBoost和GBDT的差异所在。
上个公式中,树的复杂度计算公式如下:
Ω ( f ) = γ T + 2 1 λ ∣ ∣ w ∣ ∣ 2 \Omega(f)=\gamma T+^{1}_{2}\lambda||w||^2 Ω(f)=γT+21λ∣∣w2
其中, T为树的叶子节点个数, w j w_j wj为第j个节点的权重。叶子节点越少模型越简单,此外叶子节点也不应该含有过高的权重。
L ( t ) = ∑ i n l ( y i , y ′ i ( t − 1 ) + f t ( x i ) ) + Ω ( f t ) L(t)=\sum_{i}^nl(y_i,y{'}_i(t-1)+f_t(x_i))+\Omega(f_t) L(t)=inl(yi,yi(t1)+ft(xi))+Ω(ft)
按照二阶泰特展开,
L ( t ) ≈ ∑ i n [ l ( y i , y ′ i ( t − 1 ) ) + g i f t ( x i ) + 0.5 h i f t 2 ( x i ) ] + Ω ( f t ) L(t)\approx\sum_{i}^n[l(y_i,y{'}_i(t-1))+g_if_t(x_i)+0.5h_if_t^2(x_i)]+\Omega(f_t) L(t)in[l(yi,yi(t1))+gift(xi)+0.5hift2(xi)]+Ω(ft)
由于前k-1个树的结果已经得到,所以可以把他们作为常量进行简化,即:
L ′ ( t ) = ∑ i n [ g i f t ( x i ) + 0.5 h i f t 2 ( x i ) ] + Ω ( f t ) L'(t)=\sum_{i}^n[g_if_t(x_i)+0.5h_if_t^2(x_i)]+\Omega(f_t) L(t)=in[gift(xi)+0.5hift2(xi)]+Ω(ft)
其中 g i g_i gi是损失函数 l ( y i , y ′ i ( t − 1 ) l(y_i,y{'}_i(t-1) l(yi,yi(t1) y ′ i ( t − 1 ) y{'}_i(t-1) yi(t1)的一阶导, 就是在梯度提升树中第t棵树要拟合的那个值。 h i h_i hi是二阶导,XGBoost 引入二阶导一方面是为了增加精度,另一方面也是为了能够自定义损失函数,二阶泰勒展开可以近似大量损失函数。顺便提一下,xgboost工具支持自定义代价函数,只要函数可一阶和二阶求导。
进一步化简,
m i n ( o b j ) = − 2 1 ∑ j = 1 T G j 2 / ( H j 2 + λ ) + γ T min(obj)=-^1_{2}\sum_{j=1}^T {G_j^2/({H_j^2+\lambda)}} +\gamma T min(obj)=21j=1TGj2/(Hj2+λ)+γT
其中,T为这棵树的叶节点个数, G j G_j Gj为节点 j所含所有样本的一阶导数 g j g_j gj 之和; H j H_j Hj为节点 j所含所有样本的二阶导数 h j h_j hj之和。

2分裂算法

下面分别通过原论文中的两个伪代码略微讲一下节点分裂的依据。
分裂算法1:贪心
在这里插入图片描述
XGBoost使用了和CART回归树一样的想法,利用贪婪算法,将所有特征升序排序,然后遍历所有特征的所有特征划分点,不同的是使用的目标函数不一样。具体做法就是求分裂后的目标函数值比分裂前的目标函数的增益。

分裂算法2:近似
在这里插入图片描述
贪心算法可以得到最优解,但当数据量太大时则无法读入内存进行计算,近似算法则大大降低了计算量,给出了近似最优解。
对于每个特征,只考察分位点可以减少计算复杂度。近似算法简单来说,就是对每个特征 k 都确定l个候选切分点 ,然后根据这些候选切分点把相应的样本放入对应的桶中,对每个桶的 g i , h i g_i,h_i gi,hi进行累加。最后在候选切分点集合上贪心查找。因此相比贪心来说,在计算上会少很多。

3缩减和列抽样

除了对树复杂度的正则项之外,作者还选用了两个正则化方法。

一是缩减。XGBoost 在进行完一次迭代后,会将新加进来的树的叶子节点权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。传统GBDT的实现也有学习速率;步长越小,越有可能找到更精确的最佳值,更多的空间被留给了后面建立的树,但迭代速度会比较缓慢。

二是列抽样。XGBoost借鉴了随机森林的做法,每次分裂的时候随机选择m个特征计算增益,而不是全部特征都考虑。不仅能降低过拟合,还能减少计算。这也是XGBoost异于传统GBDT的一个特性。

4并行计算

前面说过Boosting是一种串行的结构,因此XGBoost的并行不是树粒度的并行,XGBoost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。XGBoost的并行是在特征粒度上的。我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点)。而XGBoost在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。

四 总结

XGBoost是集成学习中的大杀器,因为高效准确和易用,不仅在各种机器学习竞赛中经常出现,甚至工业中也不乏它的身影。但是XGBoost的细节远不知上面提到的这些,后续有机会再做详细学习整理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值