之前文章分享了AdaBoost的算法原理GBDT算法原理,这篇文章将讲解XGBoost,建议看本文之前,先看一下AdaBoost算法和GBDT算法的原理。码字不易,喜欢请点赞!!!
【机器学习】十六、XGBoost算法原理讲解

1.XGBoost简介

XGBoost自从提出以来,可谓就开始广为流传,并且在kaggle竞赛中屡获佳绩。在机器学习的算法中,XGBoost可谓是终极大杀器。本人学习XGBoost提出者陈天奇博士以及博客园刘建平大佬的文章后,根据自己的理解写了这篇博客,仅供自己学习和来着参考,如有错误,欢迎各位批评指正。

2.XGBoost损失函数

2.1GBDT损失函数

在上一篇文章中分享了GBDT算法的原理,其中提到,GBDT算法是每次通过拟合残差来进行预测,并且使用损失函数的负梯度作为当前模型的残差近似值。
rmi=[L(y,f(xi))f(xi)]f(x)=fm1(x)r_{mi}=-[\frac{∂L(y,f(x_i))}{∂f(x_i)}]_{f(x)=f_{m-1}(x)}
这里的负梯度其实就是损失函数的一阶泰勒展开。

泰勒展开说明:
首先,泰勒展开公式为:
f(x)=f(x0)+f(x0)1!(xx0)+f(x0)2!(xx0)2+...+fn(x0)n!(xx0)n+Rn(x)f(x)=f(x_0)+\frac{f^{'}(x_0)}{1!}(x-x_0)+\frac{f^{''}(x_0)}{2!}(x-x_0)^2+...+\frac{f^n(x_0)}{n!}(x-x_0)^n+R_n(x)
并且GBDT算法的损失函数为:
Lm=i=1NL(yi,fm1(xi)+hm(xi))L_m=\sum_{i=1}^{N}L(y_i,f_{m-1}(x_i)+h_m(x_i))
因此有GBDT算法的损失函数的泰勒展开为:
Lm=i=1NL(yi,fm1(xi)+hm(xi))i=1N[L(yi,fm1(xi))L(yi,fm1(xi))fm1(xi)hm(xi)+12!L2(yi,fm1(xi))fm12(xi)hm2(xi)+...+1n!Ln(yi,fm1(xi))fm1n(xi)hmn(xi)+Rn(x)] \begin{aligned} L_m &=\sum_{i=1}^{N}L(y_i,f_{m-1}(x_i)+h_m(x_i)) \\ &=\sum_{i=1}^{N}[L(y_i,f_{m-1}(x_i))+\frac{∂L(y_i,f_{m-1}(x_i))}{∂f_{m-1}(x_i)}h_m(x_i) \\ & + \frac{1}{2!}\frac{∂L^2(y_i,f_{m-1}(x_i))}{∂f^2_{m-1}(x_i)}h^2_m(x_i)+...+\frac{1}{n!}\frac{∂L^n(y_i,f_{m-1}(x_i))}{∂f^n_{m-1}(x_i)}h^n_m(x_i)+R_n(x)] \end{aligned}
从损失函数的泰勒展开公式可以知道,GBDT使用的负梯度作为残差的近似值,其实就是使用的一阶泰勒展开。

2.2XGBoost损失函数

上一节说了GBDT的损失函数为Lm=i=1NL(yi,fm1(xi)+hm(xi))L_m=\sum_{i=1}^{N}L(y_i,f_{m-1}(x_i)+h_m(x_i)),而XGBoost算法的损失函数,是在此基础上,添加了正则化项:
γJ+λ2j=1Jwmj2\gamma J+\frac{\lambda}{2}\sum_{j=1}^{J}w_{mj}^2
其中参数γλ\gamma 和 \lambda为正则化系数,JJ为叶子节点数,而wmjw_{mj}和GBDT章节中的cmjc_{mj}是一个意思,表示第mm棵树的第JJ个叶子节点的最优值,只是XGBoost的论文里用的是ww表示叶子区域的值,因此这里和论文保持一致。

因此,可以得到XGBoost算法的损失函数为:
Lm=i=1NL(yi,fm1(xi)+hm(xi))+γJ+λ2j=1Jwmj2L_m=\sum_{i=1}^{N}L(y_i,f_{m-1}(x_i)+h_m(x_i))+\gamma J+\frac{\lambda}{2}\sum_{j=1}^{J}w_{mj}^2
优化目标为,损失函数极小化,得到第mm棵树最优的JJ个叶子节点区域,以及每个叶子节点对应的最优解wmjw_{mj}。前面说过GBDT是拟合泰勒展开式的一阶导数,而XGBoost则期望直接基于损失函数的二阶泰勒展开式来求解,因此有下式:
Lm=i=1NL(yi,fm1(xi)+hm(xi))+γJ+λ2j=1Jwmj2i=1N[L(yi,fm1(xi))L(yi,fm1(xi))fm1(xi)hm(xi)+12!L2(yi,fm1(xi))fm12(xi)hm2(xi)]+γJ+λ2j=1Jwmj2 \begin{aligned} L_m &=\sum_{i=1}^{N}L(y_i,f_{m-1}(x_i)+h_m(x_i))+\gamma J+\frac{\lambda}{2}\sum_{j=1}^{J}w_{mj}^2 \\ & \approx\sum_{i=1}^{N}[L(y_i,f_{m-1}(x_i))+\frac{∂L(y_i,f_{m-1}(x_i))}{∂f_{m-1}(x_i)}h_m(x_i) + \frac{1}{2!}\frac{∂L^2(y_i,f_{m-1}(x_i))}{∂f^2_{m-1}(x_i)}h^2_m(x_i)]+\gamma J+\frac{\lambda}{2}\sum_{j=1}^{J}w_{mj}^2 \end{aligned}
为了便于推到,令第ii个样本在第mm棵树上的一阶导数为:
gmi=L(yi,fm1(xi))fm1(xi)g_{mi}=\frac{∂L(y_i,f_{m-1}(x_i))}{∂f_{m-1}(x_i)}
令第ii个样本在第mm棵树上的二阶导数为:
lmi=L2(yi,fm1(xi))fm12(xi) l_{mi} = \frac{∂L^2(y_i,f_{m-1}(x_i))}{∂f^2_{m-1}(x_i)}
因此有:
Lm=i=1NL(yi,fm1(xi)+hm(xi))+γJ+λ2j=1Jwmj2i=1N[L(yi,fm1(xi))gmihm(xi)+12lmihm2(xi)]+γJ+λ2j=1Jwmj2 \begin{aligned} L_m &=\sum_{i=1}^{N}L(y_i,f_{m-1}(x_i)+h_m(x_i))+\gamma J+\frac{\lambda}{2}\sum_{j=1}^{J}w_{mj}^2 \\ & \approx\sum_{i=1}^{N}[L(y_i,f_{m-1}(x_i))+g_{mi}h_m(x_i) + \frac{1}{2}l_{mi}h^2_m(x_i)]+\gamma J+\frac{\lambda}{2}\sum_{j=1}^{J}w_{mj}^2 \end{aligned}
损失函数中L(yi,fm1(xi))L(y_i,f_{m-1}(x_i))为常数,对最小化无影响,可以去掉,因此有:
Lmi=1N[gmihm(xi)+12lmihm2(xi)]+γJ+λ2j=1Jwmj2 \begin{aligned} L_m & \approx\sum_{i=1}^{N}[g_{mi}h_m(x_i) + \frac{1}{2}l_{mi}h^2_m(x_i)]+\gamma J+\frac{\lambda}{2}\sum_{j=1}^{J}w_{mj}^2 \end{aligned}
并且对于第mm棵树最优的jj个叶子节点,其节点的值都为wmjw_{mj},因此有:
Lmi=1N[gmihm(xi)+12lmihm2(xi)]+γJ+λ2j=1Jwmj2=j=1J[xiRmjgmiwmj+12xiRmjlmiwmj2]+γJ+λ2j=1Jwmj2=j=1J[(xiRmjgmi)wmj+12(xiRmjlmi+λ)wmj2]+γJ \begin{aligned} L_m & \approx\sum_{i=1}^{N}[g_{mi}h_m(x_i) + \frac{1}{2}l_{mi}h^2_m(x_i)]+\gamma J+\frac{\lambda}{2}\sum_{j=1}^{J}w_{mj}^2 \\ & = \sum_{j=1}^{J}[\sum_{x_i \in R_{mj}}g_{mi}w_{mj}+\frac{1}{2}\sum_{x_i \in R_{mj}}l_{mi}w_{mj}^2]+\gamma J+\frac{\lambda}{2}\sum_{j=1}^{J}w_{mj}^2 \\ & =\sum_{j=1}^{J}[(\sum_{x_i \in R_{mj}}g_{mi})w_{mj}+\frac{1}{2}(\sum_{x_i \in R_{mj}}l_{mi}+\lambda)w_{mj}^2]+\gamma J \end{aligned}
此时,为了便于推导,令每个叶子节点处的一阶导数为:
Gmj=xiRmjgmiG_{mj}=\sum_{x_i \in R_{mj}}g_{mi}
令每个叶子节点处的二阶导数为:
Lmj=xiRmjlmiL_{mj}=\sum_{x_i \in R_{mj}}l_{mi}
因此,最终损失函数为:
Lm=j=1J[Gmjwmj+12(Lmj+λ)wmj2]+γJL_m=\sum_{j=1}^{J}[G_{mj}w_{mj}+\frac{1}{2}(L_{mj}+\lambda)w_{mj}^2]+\gamma J

2.3XGBoost损失函数优化

前面GBDT原理小节提到,GBDT步骤是,先计算残差,然后根据残差拟合决策树,然后计算决策树每个叶子节点的最优取值。
在XGBoost中,将后面两步统一做,即一次求解出决策树最优的所有JJ个叶子节点区域,以及每个叶子节点处的最优值wmjw_{mj}。因此可以将这个问题拆分成两个问题:
(1)在得到决策树的叶子节点区域之后,如何计算最优值wmjw_{mj}
(2)对当前决策树做子树分裂决策时,应该如何选择哪个特征和特征值进行分裂,使最终我们的损失函数LmL_m最小?
首先对于第一个问题,在得到决策树的叶子节点区域之后,最优值wmjw_{mj}可以通过对损失函数基于wmjw_{mj}求导,令导数为0,即可得到叶子节点区域最优解:
wmj=GmjLmj+λw_{mj}=-\frac{G_{mj}}{L_{mj}+\lambda}
在解决第二个为题时,首先将叶子节点区域最优解wmjw_{mj}代入损失函数得到:
Lm=12j=1JGmj2Lmj+λ+γJL_m=-\frac{1}{2}\sum_{j=1}^{J}\frac{G_{mj}^2}{L_{mj}+\lambda}+\gamma J
在每次对某个叶子节点进行分裂时,将对在当前节点产生左子树和右子树,假设当前节点左右子树的一阶二阶导数和为GLLLGRLRG_L,L_L,G_R,L_R,因此每次分裂时,目标是最大化的减小损失函数,即最大化下式:
[12(GL+GR)2(LL+LR)+λ+γJ][12GL2LL+λ12GR2LR+λ+γ(J+1)][-\frac{1}{2}\frac{(G_L+G_R)^2}{(L_L+L_R)+\lambda}+\gamma J]-[-\frac{1}{2}\frac{G_L^2}{L_L+\lambda}-\frac{1}{2}\frac{G_R^2}{L_R+\lambda}+\gamma (J+1)]
化简得到,我们期望最大化的是:
max12GL2LL+λ+12GR2LR+λ12(GL+GR)2(LL+LR)+λγmax\frac{1}{2}\frac{G_L^2}{L_L+\lambda}+\frac{1}{2}\frac{G_R^2}{L_R+\lambda}-\frac{1}{2}\frac{(G_L+G_R)^2}{(L_L+L_R)+\lambda}-\gamma
因此,每次进行左右子树分裂时,只需选择目标函数最大化的特征分裂处即可。

3.XGBoost算法流程

XGBoost算法流程如下:
输入:训练样本集T={(x1,y1),(x2,y2),...,(xN,yN)}T= \{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\},其中,xiχRnx_i\in \chi \in R^nyiYRy_i\in Y \in R;损失函数L(y,f(x))L(y,f(x));正则化系数λγ\lambda 和\gamma
输出:强学习器f(x)f(x)
对于m=1,2,...,Mm=1,2,...,M
(1)计算第ii个样本当前损失函数LL基于fm1(x)f_{m-1}(x)的一阶导数gmig_{mi}和二阶导数lmil_{mi},计算所有样本的一阶导数和Gm=i=1NgmiG_m=\sum_{i=1}^{N}g_{mi},二阶导数和Lm=i=1NlmiL_m=\sum_{i=1}^{N}l_{mi}
(2)基于当前节点尝试分裂决策树,默认分数score=0
对于特征序号k=1,2,...,Kk=1,2,...,K
(a)GL=0,HL=0G_L=0 ,H_L=0
(b.1)将样本按特征k从小到大排列,依次取出第i个样本,依次计算当前样本放入左子树后,左右子树一阶和二阶导数和:
GL=GL+gmi,GR=GGLG_L=G_L+g_{mi},G_R=G-G_LLL=LL+lmi,LR=LLLL_L=L_L+l_{mi},L_R=L-L_L
(b.2)尝试更新最大的分数:
score=max{score,12GL2LL+λ+12GR2LR+λ12(GL+GR)2(LL+LR)+λγ}score=max\{score,\frac{1}{2}\frac{G_L^2}{L_L+\lambda}+\frac{1}{2}\frac{G_R^2}{L_R+\lambda}-\frac{1}{2}\frac{(G_L+G_R)^2}{(L_L+L_R)+\lambda}-\gamma\}
(3)基于最大score对应的划分特征和特征值分裂子树。
(4)如果最大score为0,则当前决策树建立完毕,计算所有叶子区域的wmjw_{mj},得到弱学习器hm(x)h_{m}(x),更新强学习器ft(x)f_t(x),进入下一轮弱学习器迭代.如果最大score不是0,则转到第(2)步继续尝试分裂决策树。

参考文献
1.陈天奇论文:https://arxiv.org/pdf/1603.02754.pdf
2.陈天奇PPT:https://homes.cs.washington.edu/~tqchen/pdf/BoostedTree.pdf
3.刘建平关于XGBoost讲解的博客:https://www.cnblogs.com/pinard/p/10979808.html
4.本人的AdaBoost总结:https://blog.csdn.net/Asher117/article/details/103517786
5.本人的GBDT总结:https://blog.csdn.net/Asher117/article/details/103523968

相关文章: