通俗理解xgboost及推导

前言

     本文总结xgboost,我们的举例大部分都是针对二分类场景,毕竟实际工作中分类的场景是比较多的,我们就顺着分类场景这条线讲。大佬们有问题的欢迎留言交流和指教,一起学习吧。

    

☆☆☆ 算法目录导航页,包含基础算法、高级算法、机器学习算法等☆☆☆

    

一、决策树

   决策树是树模型中最简单最基础的,其他的树模型都是在这基础衍生出来的,所以先讲下什么是决策树。顾名思义,决策树首先是一棵树的样子,树如何生长即如何分裂,即为决策,它可以解决分类问题,最终的分类结果是取决于落到的那个叶子节点。

在这里插入图片描述

   然后,我们从一个实际问题入手了解决策树的应用: 老师让你统计下班里男女的数量,你会怎么区分男女?很快,你会审视每一个学生,头发长的是女生,头发短的是男生,通过 头发长短 迅速将学生分开。但是,头发长短 也不一定准确吧,很多男生也留长发啊。OK,那就用有无喉结来划分吧,好像有的女生也有喉结,这可怎么办呢,纠结死了,到底是用‘有无喉结’还是‘头发长短’来划分呢?
  此时,我们如何判断哪种划分是最优的?而且需要量化它。用信息熵来量化到底是选【头发长短】还是【有无喉结】。
   什么是熵(Entropy)?就是不纯度的一种度量指标。假定当前样本集合D中第k类样本所占的比例为p_k,则D的信息熵定义为:

E n t ( D ) = − ∑ k = 1 ∣ Y ∣ p k log ⁡ 2 p k Ent(D)=-\sum_{k=1}^{|\mathcal{Y}|} p_{k} \log _{2} p_{k} Ent(D)=k=1Ypklog2pk

  信息熵约定:若p=0,则plogp=0,Ent(D)最小值为0,最大值为log|y|。Ent(D)的值越小,纯度越高。
   那具体怎么使用这个熵呢?我们用gain增益,注意:这个增益在整个树模型中都通用,针对熵这种量化指标可以这样计算增益: g a i n ( D , 长 短 ) = Ent ⁡ ( D ) − ∑ y = 1 n ∣ D v ∣ ∣ D ∣ Ent ⁡ ( D v ) gain(D,长短) = \operatorname{Ent}(D)-\sum_{y=1}^{n} \frac{\left|D^{v}\right|}{|D|} \operatorname{Ent}\left(D^{v}\right) gain(D,)=Ent(D)y=1nDDvEnt(Dv)
   其中,D为总的样本集合,Ent(D)为D的熵,D_v为根据某一个特征分桶后的子样本集合,Ent(D_v)为子样本集合的熵。
   举例:

假如西瓜的色泽有3种,青、黑、白,

   计算过程:
   ① 划分之前, 正样本数3,负样本数5,则划分前的信息熵为: E n t ( D ) = − 3 8 log ⁡ 2 3 8 = 0.1597 Ent(D) = -\frac{3}{8} \log _{2} \frac{3}{8}=0.1597 Ent(D)=83log283=0.1597
   ② 根据头发长短划分:
         头发长的子集{1,2,3,7,8}共5个样本, 其中正样本为1个,则: E n t ( D l o n g ) = − 1 5 log ⁡ 2 1 5 = 0.1398 Ent(D^{long}) = -\frac{1}{5} \log _{2} \frac{1}{5}=0.1398 Ent(Dlong)=51log251=0.1398
         头发短的子集{4,5,6}共3个样本, 其中正样本为2个,则: E n t ( D s h o r t ) = − 2 3 log ⁡ 2 2 3 = 0.1174 Ent(D^{short}) = -\frac{2}{3} \log _{2} \frac{2}{3}=0.1174 Ent(Dshort)=32log232=0.1174
         头发长的比例为5/8,短的比例3/8,则对上面两个熵加权求和得: E n t ( D s h o r t + l o n g ) = 5 8 ∗ E n t ( D l o n g ) + 3 8 ∗ E n t ( D s h o r t ) = 0.1314 Ent(D^{short+long}) = \frac{5}{8} *Ent(D^{long}) +\frac{3}{8} * Ent(D^{short}) =0.1314 Ent(Dshort+long)=85Ent(Dlong)+83Ent(Dshort)=0.1314
         则增益为: g a i n ( D , 长 短 ) = Ent ⁡ ( D ) − E n t ( D s h o r t + l o n g ) = 0.0283 gain(D,长短) = \operatorname{Ent}(D)-Ent(D^{short+long}) = 0.0283 gain(D,)=Ent(D)Ent(Dshort+long)=0.0283
   ③ 同理,我们可以计算 gain(D,喉结),然后选择gain较大的去划分即可。OK,通透了。
  决策树的分裂算法通常有3种,基于信息熵的ID3和C4.5, 基于基尼指数的CART:
   ① ID3
   上面我们计算过程就是ID3算法,基于信息增益。
   缺点:优先选择有较多属性值的特征。比如学号,45个学生,把学号考虑进来,最终会有45个桶(1-45号),新来一个同学是46号则无法通过模型来判断46号是什么样的学生,所以泛化能力差,模型学的过拟合了。
  ② C4.5
   这个算法是基于信息增益率,是对ID3的改进。
   C4.5优点:产生的分类规则易于理解,准确率较高。
   C4.5缺点:在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,因而导致算法的低效。此外,C4.5只适合于能够驻留于内存的数据集,当训练集大得无法在内存容纳时程序无法运行。
   C4.5公式: g a i n r = Gain ⁡ ( D , A ) Splitlnformation ( D , A ) gain_{r}= \frac{\operatorname{Gain}(D, A)}{\text {Splitlnformation}(D, A)} gainr=Splitlnformation(D,A)Gain(D,A)
  其中, Splitlnformation ( D , A ) = − ∑ i = 1 n ∣ D v ∣ ∣ D ∣ log ⁡ 2 ∣ D v ∣ ∣ D ∣ \text {Splitlnformation}(D, A)= -\sum_{i=1}^{n} \frac{\left|D^{v}\right|}{|D|} \log _{2} \frac{\left|D^{v}\right|}{|D|} Splitlnformation(D,A)=i=1nDDvlog2DDv
  ③ CART,分类回归树,基于基尼指数,最小化不纯度,而不是最大化信息增益。也就是说CART是朝着基尼系数减小的方向生长,而ID3和C4.5是朝着增益大的方向生长。不管是分类还是回归,原理都差不多,只不过分裂时选择损失不同,分类可选某种增益,回归可选MSE等。
   另外,xgboost的基学习器就是CART。

二、集成学习 ensemble learning

   集成学习 (ensemble learning) 是通过构建并结合多个基学习器来完成学习任务 。一般结构为:
   ① 产生一组基学习器;
   ② 通过某种策略将它们结合起来;
   集成学习通过将多个学习器进行组合,通常可以获得比单一学习器显著优越的泛化性能。
   常见的方法有:Bagging、Boosting、Stacking,除此之外还有Voting、Averaging、Blending。
   ① Voting
     Voting是一种很思想很简单的集成策略。主要应用于分类问题
     几种常见的Voting方法有:
     1、绝对多数投票法(majority voting):也就是若某个标记的得票超过了半数,则预测为该标记,否则拒绝预测。
     2、相对多数投票法(plurality voting): 即预测为得票最多的标记,若同时有多个标记,那么从中随机选取一个。
     3、加权投票法(weighted voting)即为不同的标记赋予不同的权重,最后再按照相对多数投票法来预测。
   ② Averaging
     Averaging即是一种取平均的思想,从整体的角度上来提高预测的鲁棒性,通常用于回归问题
     几种常见的Averaging方法:
     1、简单平均法(simple averaging)
     2、加权平均法(weighted averaging)
   ③ Bagging
     代表为RF。
     具体实现:对样本进行有放回的随机采样,基学习器间并行计算,相互独立,各自输出一个结果,最后通过投票的方式输出最终结果。目的是减小方差,减小波动性,使得模型更稳定,泛化能力更强。调参的时候要考虑模型的精度。

在这里插入图片描述

   ④ Boosting 提升
     代表为AdaBoost、GBDT、XGBoost 等。
     每一步生成一个弱模型(基学习器),加权累加到总模型中。其实上面我们已经说过了,集成学习就两点,1是先生成多个基学习器,2再通过某种策略组合起来。所以,boosting区别于bagging的是多个基学习器之间有依赖关系,它是串行的。
     AdaBoost:Adaptive Boosting,自适应增强,很简单,就是通过样本加权的方式,达到错误率小或者预先设置的迭代次数。每一步迭代中将分错的样本权重增强。
     GBDT、xgboost: 与AdaBoost不同,GBDT每一次的计算都是为了减少上一次的残差,进而在残差减少(负梯度)的方向上建立一个新的模型。
算法过程举例(adaboost): 在这里插入图片描述
boosting Adaboost详细求解过程参考
   ⑤ Stacking
     Stacking的策略为将t-1个基分类器的输出y作为第t个基分类器的输入x。它是一种分层的结构,如下图:

在这里插入图片描述

     与boosting和bagging的区别:boosting和bagging中一般都为相同的模型,比如基学习器都是CART。而Stacking是不同的模型,比如M2可以是xgboost、KNN、SVM等,M3可以是LR等。
   ⑥ Blending
     blending和stacking类似,我的理解是Stacking是堆叠,Blending是混合,如下图:

在这里插入图片描述

     同样的,图中M可以是KNN、SVM等。

三、xgboost直观理解

  xgboost的算法通俗来说就是不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数,去拟合上次预测的残差。

在这里插入图片描述

   xgb预测结果为每棵树预测得分的累加和,如下图:

在这里插入图片描述

四、xgboost如何建模( 定义目标函数 )

   xgboost到底要做什么呢?上面已经提过: 每次添加一颗树( f t f_t ft), 然后去拟合前一棵树预测的残差。
   已知第t-1颗树,求第t颗树的结构 f t f_t ft,目标函数(可看成【单颗树的结构分数】,模型预测的最终结果要把每棵树的这个得分加起来)可写成:

J ( f t ) = S t r u c t u r e _ S c o r e ( f t ) = ∑ i = 1 n L ( y i , y ^ i ( t − 1 ) + f t ( x i ) ) + Ω ( f t ) + C   ( 式 ① ) J\left(f_{t}\right)=Structure\_Score(f_t)=\sum_{i=1}^{n} L\left(y_{i}, \hat{y}_{i}^{(t-1)}+f_{t}\left(x_{i}\right)\right)+\Omega\left(f_{t}\right)+\text {C } \ (式①) J(ft)=Structure_Score(ft)=i=1nL(yi,y^i(t1)+ft(xi))+Ω(ft)+ 

   其中,i为第i个样本,L为某种损失函数, y i y_i yi为实际值, y ^ i ( t − 1 ) \hat{y}_{i}^{(t-1)} y^i(t1)为第t-1颗树的预测值, f t ( x i ) f_t(x_i) ft(xi)为第t颗树的样子, Ω ( f t ) Ω(f_t) Ω(ft)为正则项, f t f_t ft,C为常数项。注意:这里不同于其他算法的地方在于参数是函数空间,即把函数f当成另一个函数的参数。因此,目标函数其实是参数为 f t f_t ft的函数。

五、目标函数简化

   此时的参数是指函数空间 f t f_t ft,我们先化简我们的目标函数:
   ① 利用泰勒二阶展开近似原目标函数
   泰勒二阶展开: f ( x + Δ x ) ≈ f ( x ) + f ′ ( x ) Δ x + 1 2 f ′ ′ ( x ) Δ x 2 f(x+\Delta x) \approx f(x)+f^{\prime}(x) \Delta x+\frac{1}{2} f^{\prime \prime}(x) \Delta x^{2} f(x+Δx)f(x)+f(x)Δx+21f(x)Δx2
   我们令:

g i = ∂ L ( y i , y ^ i ( t − 1 ) ) ∂ y ^ i ( t − 1 ) h i = ∂ 2 L ( y i , y ^ i ( t − 1 ) ) ∂ y ^ i ( t − 1 ) g_{i}=\frac{\partial L\left(y_{i}, \hat{y}_{i}^{(t-1)}\right)}{\partial \hat{y}_{i}^{(t-1)}} \quad h_{i}=\frac{\partial^{2} L\left(y_{i}, \hat{y}_{i}^{(t-1)}\right)}{\partial \hat{y}_{i}^{(t-1)}} gi=y^i(t1)L(yi,y^i(t1))hi=y^i(t1)2L(yi,y^i(t1))

  利用泰勒二阶展开近似目标函数得:

J ( f t ) ≈ ∑ i = 1 n [ L ( y i , y ^ i ( t − 1 ) ) + g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + Ω ( f t ) + C J\left(f_{t}\right) \approx \sum_{i=1}^{n}\left[L\left(y_{i}, \hat{y}_{i}^{(t-1)}\right)+g_{i} f_{t}\left(x_{i}\right)+\frac{1}{2} h_{i} f_{t}^{2}\left(x_{i}\right)\right]+\Omega\left(f_{t}\right)+C J(ft)i=1n[L(yi,y^i(t1))+gift(xi)+21hift2(xi)]+Ω(ft)+C

  因为,第t-1颗树的预测值是已知的,所以 y ^ i ( t − 1 ) \hat{y}_{i}^{(t-1)} y^i(t1)是已知的,则 L ( y i , y ^ i ( t − 1 ) ) L\left(y_{i}, \hat{y}_{i}^{(t-1)}\right) L(yi,y^i(t1))就是已知的,所以将它移入常数项C得:
J ( f t ) = ∑ i = 1 n [ g i f t ( x i ) + 1 2 h i f f 2 ( x i ) ] + Ω ( f t ) + C ( 式 ② ) J(f_{t})=\sum_{i=1}^{n}\left[g_{i} f_{t}\left(x_{i}\right)+\frac{1}{2} h_{i} f_{f}^{2}\left(x_{i}\right)\right]+\Omega\left(f_{t}\right)+C (式②) J(ft)=i=1n[gift(xi)+21hiff2(xi)]+Ω(ft)+C
   ② 正则项
   Ω ( f t ) = γ ⋅ T + λ ⋅ 1 2 ∑ j = 1 T ( w j 2 ) ( 式 ③ ) \Omega\left(f_{t}\right)=\gamma \cdot T+\lambda \cdot \frac{1}{2} \sum_{j=1}^{T}\left(w_{j}^{2}\right)(式③) Ω(ft)=γT+λ21j=1T(wj2)
   其中,T为第t颗树叶子节点的数量,w为叶权值,γ和λ都为超参数。 γ ⋅ T \gamma \cdot T γT相当于预剪枝。
   我们把树看成是一个函数 f ( x i ) f(x_i) f(xi),输出就是判定的结果,这个结果最终是由第q个叶子节点的权值 w q w_q wq决定,所以 f ( x i ) = w q ( x i ) ( 式 ④ ) f(x_i) = w_q(x_i)(式④) f(xi)=wq(xi)
   将③ ④带入②得:
   J ( f t ) = ∑ i = 1 n [ g i w q ( x i ) + 1 2 h i w q ( x i ) 2 ] + γ ⋅ T + λ ⋅ 1 2 ∑ j = 1 T w j 2 + C J(f_{t})=\sum_{i=1}^{n}\left[g_{i} w_{q\left(x_{i}\right)}+\frac{1}{2} h_{i} w_{q\left(x_{i}\right)}^{2}\right]+\gamma \cdot T+\lambda \cdot \frac{1}{2} \sum_{j=1}^{T} w_{j}^{2}+C J(ft)=i=1n[giwq(xi)+21hiwq(xi)2]+γT+λ21j=1Twj2+C
   n个样本落在T个不同的叶子上,那么可以等价的按不同的叶子将样本进行区分,即按T将落在同一个叶子上的样本进行求和,又可继续得:

J ( f t ) = ∑ j = 1 T [ ( ∑ i ∈ I g i ) w j + 1 2 ( ∑ i ∈ I j h i ) w j 2 ] + γ ⋅ T + λ ⋅ 1 2 ∑ j = 1 T w j 2 + C J(f_{t})=\sum_{j=1}^{T}\left[\left(\sum_{i \in I} g_{i}\right) w_{j}+\frac{1}{2}\left(\sum_{i \in I_{j}} h_{i}\right) w_{j}^{2}\right]+\gamma \cdot T+\lambda \cdot \frac{1}{2} \sum_{j=1}^{T} w_{j}^{2}+C J(ft)=j=1T(iIgi)wj+21iIjhiwj2+γT+λ21j=1Twj2+C

  令 G j = ( ∑ i ∈ I j g i ) , H j = ( ∑ i ϵ I j h i ) G_{j}=\left(\sum_{i \in I_{j}} g_{i}\right), H_{j}=\left(\sum_{i \epsilon I_{j}} h_{i}\right) Gj=(iIjgi),Hj=(iϵIjhi)
   目标函数最终化简为:

J ( f t ) = ∑ j = 1 T [ G j w j + 1 2 ( H j + λ ) w j 2 ] + γ ⋅ T + C J\left(f_{t}\right)=\sum_{j=1}^{T}\left[G_{j} w_{j}+\frac{1}{2}\left(H_{j}+\lambda\right) w_{j}^{2}\right]+\gamma \cdot T+C J(ft)=j=1T[Gjwj+21(Hj+λ)wj2]+γT+C

六、目标函数优化

   目标函数是一个分数,分数越小,树结构 f t f_t ft越好,最小化的通用套路,求偏导等于0:
   ∂ J ( f t ) ∂ w j = G j + ( H j + λ ) w j = 0 \frac{\partial J\left(f_{t}\right)}{\partial w_{j}}=G_{j}+\left(H_{j}+\lambda\right) w_{j}=0 wjJ(ft)=Gj+(Hj+λ)wj=0
   w j = − G j H j + λ w_{j}=-\frac{G_{j}}{H_{j}+\lambda} wj=Hj+λGj
   带入目标函数,最终得到:
   S t r u c t u r e _ S c o r e ( f t ) = − 1 2 ∑ j = 1 T G j 2 H j + λ + γ ⋅ T Structure\_Score(f_t)=-\frac{1}{2} \sum_{j=1}^{T} \frac{G_{j}^{2}}{H_{j}+\lambda}+\gamma \cdot T Structure_Score(ft)=21j=1THj+λGj2+γT
   由此可以看出,目标函数只跟一阶、二级导数、T有关,也就是说目标函数是衡量树结构好坏的标准: 分数score越低,树结构 f t f_t ft越好。但是,目标函数跟w没关系啊,怎么求w啊?注意:这个地方可能比较迷惑人,上面我们说过了xgb是对函数空间的优化,也就是说【xgboost不是求参数w哦,而是求 f t f_t ft】。
   打分举例(图中用Obj表示Score):

在这里插入图片描述

七、计算 - 找出最优的树结构(通过节点分裂计算得到)

   说了半天,那 f t f_t ft到底长啥样,怎么求? (求 f t f_t ft就是求树如何分裂的问题)
   既然我们的目标函数公式都有了,那不就好办了么,套路:求增益呀。
   (1)利用贪婪学习树(说的通俗一点吧,穷举所有情况,找到最优)。直接上公式(其中γ对应树的剪枝):

在这里插入图片描述

   (2)近似算法
   除了穷举法求最大增益,陈天奇大佬还提到一种找最优划分的算法,主要针对数据太大,不能直接进行计算,Time Complexity growing a tree of depth K:

在这里插入图片描述

   后来还想加速才有了histogram直方图的做法。
   这就是xgb优于传统GBDT的一个点:近似 - 直方图算法(可并行)

OK ,我们就推导到这吧!

八、xgboost相对于GBDT的优化(一共7个点,加上分裂方式不同的话共8个

   ① 传统GBDT以CART作为基分类器,xgboost还支持线性分类器,这个时候xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。分裂方式不同,由于GBDT是用CART,所以分裂方式是基于gini系数,而xgb是经过优化推导后的。
   ② 传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数。顺便提一下,xgboost工具支持自定义代价函数,只要函数可一阶和二阶求导。
   ③ xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。从Bias-variance tradeoff角度来讲,正则项降低了模型的variance,使学习出来的模型更加简单,防止过拟合,这也是xgboost优于传统GBDT的一个特性。
   ④ 列抽样(column subsampling)。xgboost借鉴了随机森林的做法,支持列抽样,不仅能降低过拟合,还能减少计算,这也是xgboost异于传统gbdt的一个特性。
   ⑤ 对缺失值的处理。对于特征的值有缺失的样本,xgboost可以自动学习出它的分裂方向。
   ⑥ xgboost工具支持并行。boosting不是一种串行的结构吗?怎么并行的?注意xgboost的并行不是tree粒度的并行,xgboost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。xgboost的并行是在特征粒度上的。我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),xgboost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。
   ⑦ 可并行的近似直方图算法。树节点在进行分裂时,我们需要计算每个特征的每个分割点对应的增益,即用贪心法枚举所有可能的分割点。当数据无法一次载入内存或者在分布式情况下,贪心算法效率就会变得很低,所以xgboost还提出了一种可并行的近似直方图算法,用于高效地生成候选的分割点。

【详细介绍和讨论】
【RF、GBDT、XGBOOST常见面试算法整理】

7. 总结:

  我们依次讲述了决策树、ensemble learning、xgboost的建模及推导过程。其实也是围绕着建模、求参的流程去分析的。希望能对大家有帮助。

8.参考资料

   1. 陈天奇大佬Paper
   2. July博客
   3. ensemble method常见方法总结
   4. bagging和boosting算法(集成学习算法)
   5. 机器学习 —— Boosting算法
   6. 机器学习–>集成学习–>Bagging,Boosting,Stacking
   7. 一文读懂xgboost原理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值