XGBoost A Scalable Tree Boosting System

XGBoost: A Scalable Tree Boosting System 论文阅读笔记


作者:陈天奇 2016年发表

XGBoost 是大规模并行 boosting tree 的工具,它是目前最快最好的开源 boosting tree 工具包,比常见的工具包快 10 倍以上。xgboost 和 GBDT 两者都是 boosting 方法,除了工程实现、解决问题上的一些差异外,最大的不同就是目标函数的定义。

1.正则化目标函数

xgboost和GBDT等boosting算法一样,由 k k k个基模型组成的加法运算式。 y i ^ = ϕ ( x i ) = ∑ k = 1 K f k ( x i ) ,   f k ∈ F \hat{y_i}=\phi(x_i)=\sum_{k=1}^{K}f_k(x_i),\ f_k\in \mathcal{F} yi^=ϕ(xi)=k=1Kfk(xi), fkF

其中 F = { f ( x ) = w q ( x ) } ( q : R m → T , w ∈ R T ) \mathcal{F}=\left \{ f(x)=w_{q(x)}\right \}(q:R^m\rightarrow T, w\in R^T) F={f(x)=wq(x)}(q:RmT,wRT)是回归树空间,其中 w q ( x ) w_{q(x)} wq(x)代表样本 x x x处在 q ( x ) q(x) q(x)节点上,取值为权值 w q ( x ) w_{q(x)} wq(x),所以模型的目标函数为:

L ( ϕ ) = ∑ i = 1 l ( y i ^ , y i ) + ∑ k Ω ( f k ) L(\phi)=\sum_{i=1}l(\hat{y_i}, y_i)+\sum_{k}\Omega(f_k) L(ϕ)=i=1l(yi^,yi)+kΩ(fk)

其中 l l l代表模型学习过程中设定的损失函数,可以为mae、mse等常见损失函数,第二项是正则项,为

Ω ( f ) = γ T + 1 2 λ ∥ w ∥ 2 \Omega(f)=\gamma T + \frac{1}{2}\lambda\|w\|^2 Ω(f)=γT+21λw2, w w w为各个叶子节点的权重,类似与LR模型的权重。

因为模型是加法模型,我们可以二阶泰勒展开

L t ( ϕ ) = ∑ i = 1 l ( y i ^ ( t ) , y i ) + ∑ k Ω ( f k ) = ∑ i = 1 l ( y i ^ ( t − 1 ) + f t ( x i ) , y i ) + ∑ k Ω ( f k ) ≈ ∑ i = 1 [ ( l ( y i ^ ( t − 1 ) , y i ) + g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + ∑ k Ω ( f k ) L^t(\phi)=\sum_{i=1}l(\hat{y_i}^{(t)}, y_i)+\sum_{k}\Omega(f_k)=\sum_{i=1}l(\hat{y_i}^{(t-1)}+f_t(x_i), y_i)+\sum_{k}\Omega(f_k)\approx\sum_{i=1}[(l(\hat{y_i}^{(t-1)}, y_i)+g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)]+\sum_{k}\Omega(f_k) Lt(ϕ)=i=1l(yi^(t),yi)+kΩ(fk)=i=1l(yi^(t1)+ft(xi),yi)+kΩ(fk)i=1[(l(yi^(t1),yi)+gift(xi)+21hift2(xi)]+kΩ(fk)

其中 g i = ∂ y ^ ( t − 1 ) l ( y i , y ^ ( t − 1 ) ) ∣ y ^ ( t − 1 ) = y i ^ ( t − 1 ) g_i=\partial_{\hat{y}^{(t-1)}} l(y_{i}, \hat{y}^{(t-1)})|_{\hat{y}^{(t-1)}=\hat{y_i}^{(t-1)}} gi=y^(t1)l(yi,y^(t1))y^(t1)=yi^(t1) h i = ∂ y ^ ( t − 1 ) 2 l ( y i , y ^ ( t − 1 ) ) ∣ y ^ ( t − 1 ) = y i ^ ( t − 1 ) h_i=\partial^2_{\hat{y}^{(t-1)}}l(y_{i}, \hat{y}^{(t-1)})|_{\hat{y}^{(t-1)}=\hat{y_i}^{(t-1)}} hi=y^(t1)2l(yi,y^(t1))y^(t1)=yi^(t1),因为此性质,xgb不仅可以用决策树当基分类器,也支持其他线性模型,只要满足一、二阶可导即可。

因为上式中 l ( y i ^ ( t − 1 ) , y i ) l(\hat{y_i}^{(t-1)}, y_i) l(yi^(t1),yi)是常数项, 我们的目标是最小化 L t ( ϕ ) L^t(\phi) Lt(ϕ),所以可以舍去,就得到了我们需要最小化的目标函数,定义 I j = { i ∣ q ( x i ) = j } I_j=\left \{ i|q(x_i)=j\right\} Ij={iq(xi)=j}是叶子节点 j j j的实例集合。

O b j ( t ) = ∑ i = 1 [ g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + ∑ k Ω ( f k ) = ∑ i = 1 [ g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + γ T + 1 2 λ ∑ j = 1 T w j 2 = ∑ j = 1 T [ ( ∑ i ∈ I j g i ) w j + 1 2 ( ∑ i ∈ I j h i + λ ) w j 2 ] + γ T Obj^{(t)}=\sum_{i=1}[g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)]+\sum_{k}\Omega(f_k)=\sum_{i=1}[g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)]+\gamma T+ \frac{1}{2}\lambda \sum^T_{j=1}w_j^2=\sum_{j=1}^T[(\sum_{i\in I_j}g_i)w_j+\frac{1}{2}(\sum_{i\in I_j}h_i+\lambda)w_j^2]+\gamma T Obj(t)=i=1[gift(xi)+21hift2(xi)]+kΩ(fk)=i=1[gift(xi)+21hift2(xi)]+γT+21λj=1Twj2=j=1T[(iIjgi)wj+21(iIjhi+λ)wj2]+γT

所以在上式中只有 w j w_j wj是未知数,对其求导等于0可得 w j ∗ = ∑ i ∈ I j g i ∑ i ∈ I j h i + λ w_j^*=\frac{\sum_{i\in I_j}g_i}{\sum_{i\in I_j}h_i + \lambda} wj=iIjhi+λiIjgi, 此时得到最优的 O b j ( t ) = − 1 2 ∑ j = 1 T ( ∑ i ∈ I j g i ) 2 ∑ i ∈ I j h i + λ + λ T Obj^{(t)}=-\frac{1}{2}\sum_{j=1}^{T}\frac{(\sum_{i\in I_j}g_i)^2}{\sum_{i\in I_j}h_i + \lambda} + \lambda T Obj(t)=21j=1TiIjhi+λ(iIjgi)2+λT,利用该式来衡量树结构的好坏。数值越小,说明树越好。

在这里插入图片描述
计算 O b j s p l i t = 1 2 [ ( ∑ i ∈ I L g i ) 2 ∑ i ∈ I L h i + λ + ( ∑ i ∈ I R g i ) 2 ∑ i ∈ I R h i + λ − ( ∑ i ∈ I g i ) 2 ∑ i ∈ I h i + λ ] − γ Obj_{split}=\frac{1}{2}[\frac{(\sum_{i\in I_L}g_i)^2}{\sum_{i\in I_L}h_i + \lambda}+\frac{(\sum_{i\in I_R}g_i)^2}{\sum_{i\in I_R}h_i + \lambda}-\frac{(\sum_{i\in I}g_i)^2}{\sum_{i\in I}h_i + \lambda}]-\gamma Objsplit=21[iILhi+λ(iILgi)2+iIRhi+λ(iIRgi)2iIhi+λ(iIgi)2]γ,来找最优分割点。

img

2.两种防止过拟合的方法

  1. Shrinkage:类似学习率,对每个学习得到的树前乘一个权重 η \eta η,以此增大后面的树学习空间。
  2. Column Subsampling: 在随机森林使用的较多,这里也可以使用防止过拟合。

3.找分割点算法

1)贪心算法

遍历每个特征计算,找最优点即可
在这里插入图片描述

2)近似算法

对于海量数据而言,计算机没有足够的内存存储所有数据点,也就无法使用贪心算法。此时使用一种近似算法。
在这里插入图片描述

  • 第一个 for 循环:对特征 k 根据该特征分布的分位数找到切割点的候选集合 S k = { s k 1 , s k 2 , ⋯   , s k l } S_k=\{s_{k1}, s_{k2}, \cdots, s_{kl}\} Sk={sk1,sk2,,skl}。XGBoost 支持 Global 策略和 Local 策略。
  • 第二个 for 循环:针对每个特征的候选集合,将样本映射到由该特征对应的候选点集构成的分桶区间中,即 s k , v > = x j k > = k , v − 1 s_{k, v}>=x_{jk}>={k, v-1} sk,v>=xjk>=k,v1 ,对每个桶统计 G , H G,H G,H 值,最后在这些统计量上寻找最佳分裂点。

对于每个特征,只考察分位点可以减少计算复杂度。

该算法会首先根据特征分布的分位数提出候选划分点,然后将连续型特征映射到由这些候选点划分的桶中,然后聚合统计信息找到所有区间的最佳分裂点。在提出候选切分点时有两种策略:

  • Global:学习每棵树前就提出候选切分点,并在每次分裂时都采用这种分割;
  • Local:每次分裂前将重新提出候选切分点。

直观上来看,Local 策略需要更多的计算步骤,而 Global 策略因为节点没有划分所以需要更多的候选点。

下图给出近似算法的具体例子,以三分位为例:

img

根据样本特征进行排序,然后基于分位数进行划分,并统计三个桶内的 G , H G,H G,H 值,最终求解节点划分的增益。

加权分位数缩略图

事实上, XGBoost 不是简单地按照样本个数进行分位,而是以二阶导数值 [公式] 作为样本的权重进行划分,如下:

我们知道模型的目标函数为:
O b j ( t ) ≈ ∑ i = 1 n [ g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + ∑ i = 1 t Ω ( f i ) Obj^{(t)}\approx \sum_{i=1}^{n}[g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)]+\sum_{i=1}^t\Omega(f_i) Obj(t)i=1n[gift(xi)+21hift2(xi)]+i=1tΩ(fi)
我们稍作整理,便可以看出 h i h_i hi 有对 loss 加权的作用。

O b j ( t ) ≈ ∑ i = 1 n [ g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + ∑ i = 1 t Ω ( f i ) = ∑ i = 1 n [ g i f t ( x i ) + 1 2 h i f t 2 ( x i ) + 1 2 g i 2 h i ] + Ω ( f t ) + C = ∑ i = 1 n 1 2 h i [ f t ( x i ) − ( − g i h i ) ] 2 + Ω ( f t ) + C \begin{aligned} Obj^{(t)} & \approx \sum_{i=1}^{n}[g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)]+\sum_{i=1}^t\Omega(f_i) \\ & = \sum_{i=1}^n[g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)+\frac{1}{2}\frac{g_i^2}{h_i}]+\Omega(f_t)+C \\ &= \sum_{i=1}^{n}\frac{1}{2}h_i[f_t(x_i)-(-\frac{g_i}{h_i})]^2+\Omega(f_t)+C \end{aligned} Obj(t)i=1n[gift(xi)+21hift2(xi)]+i=1tΩ(fi)=i=1n[gift(xi)+21hift2(xi)+21higi2]+Ω(ft)+C=i=1n21hi[ft(xi)(higi)]2+Ω(ft)+C
其中 1 2 g i 2 h i \frac{1}{2}\frac{g_i^2}{h_i} 21higi2 C C C 皆为常数。我们可以看到 h i h_i hi 就是平方损失函数中样本的权重。

对于样本权值相同的数据集来说,找到候选分位点已经有了解决方案(GK 算法),但是当样本权值不一样时,该如何找到候选分位点呢?(作者给出了一个 Weighted Quantile Sketch 算法,这里将不做介绍。)

4.稀疏感知算法

对于稀疏数据处理,xgb也提出了一种高效的处理算法,造成数据稀疏的三个原因:1)数据中缺失值较多,2)统计数据中0出现次数较多,3)人为编码造成0值很多,如one hot编码。

5.工程实现

参考https://zhuanlan.zhihu.com/p/87885678

6.优缺点

优点

  1. 精度更高:GBDT 只用到一阶泰勒展开,而 XGBoost 对损失函数进行了二阶泰勒展开。XGBoost 引入二阶导一方面是为了增加精度,另一方面也是为了能够自定义损失函数,二阶泰勒展开可以近似大量损失函数;
  2. 灵活性更强:GBDT 以 CART 作为基分类器,XGBoost 不仅支持 CART 还支持线性分类器,(使用线性分类器的 XGBoost 相当于带 L1 和 L2 正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题))。此外,XGBoost 工具支持自定义损失函数,只需函数支持一阶和二阶求导;
  3. 正则化:XGBoost 在目标函数中加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、叶子节点权重的 L2 范式。正则项降低了模型的方差,使学习出来的模型更加简单,有助于防止过拟合;
  4. Shrinkage(缩减):相当于学习速率。XGBoost 在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间;
  5. 列抽样:XGBoost 借鉴了随机森林的做法,支持列抽样,不仅能降低过拟合,还能减少计算;
  6. 缺失值处理:XGBoost 采用的稀疏感知算法极大的加快了节点分裂的速度;
  7. 可以并行化操作:块结构可以很好的支持并行计算。

缺点

  1. 虽然利用预排序和近似算法可以降低寻找最佳分裂点的计算量,但在节点分裂过程中仍需要遍历数据集;

  2. 预排序过程的空间复杂度过高,不仅需要存储特征值,还需要存储特征对应样本的梯度统计值的索引,相当于消耗了两倍的内存。

  3. 虽然利用预排序和近似算法可以降低寻找最佳分裂点的计算量,但在节点分裂过程中仍需要遍历数据集;

  4. 预排序过程的空间复杂度过高,不仅需要存储特征值,还需要存储特征对应样本的梯度统计值的索引,相当于消耗了两倍的内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值