XGBoost原理——理论基础、公式推导、单机实现
前言
XGBoost模型调参、训练、评估、保存和预测及4篇相关文章(模型评估和可解释性)已经详细介绍了XGBoost的实战应用。但对于XGBoost的加法模型、目标函数、梯度提升算法、优化方法、切分点查找、分布式计算等原理并未涉及。从本篇文章开始将逐步学习XGBoost算法原理。
机器学习的特点:入门门槛低、学习曲线陡。写给自己:这个过程就像邓宁-克鲁格心理效应曲线一样,从实战出发的我至此已经到达了“愚昧山峰”,接下来的学习目标就是“梯度下降”至“绝望之谷”,绝望之时愿能开启“开悟之路”。“大师”的地方是XGBoost的创造者陈天齐博士这样的大佬才能到达的“高原之巅”,我等凡夫俗子敬仰膜拜即可。
一.简述XGBoost
1.1算法类型:集成学习、监督学习
XGBoost属于Boosting模型,由华盛顿大学陈天齐博士提出,因在机器学习挑战赛中大放异彩而被业界所熟知。相比越来越流行的深度神经网络,XGBoost能更好的处理表格数据,并具有更强的可解释性,还具有易于调参、输入数据不变性等优势。这些在XGBoost实践篇:XGBoost模型调参、训练、评估、保存和预测 及相关文章中已做详细说明,不再赘述。
1.2应用场景:回归、分类、排序
XGBoost由多颗回归树(CART决策树)组成,每颗决策树预测真实值与之前所有决策树预测值之和的残差(残差=真实值-预测值),将所有决策树的预测值累加起来即为最终结果。下图为陈天齐博士XGBoost论文内容(下文皆简称“论文”),如图所示,两棵树tree1和tree2分别有自己的叶子节点权值,权值相加便是模型对样本的预测结果得分,例如15岁以下男性使用电脑,预测值y=tree1(节点编号2)+tree2(节点编号1)=2+0.9=2.9(节点/结点采用从上至下从左至右的方法从0开始编号)。
XGBoost广泛应用于分类、回归、排序问题,回归树产生的是连续的回归值,回归问题中将多颗决策树的预测值累加为最终结果;分类问题又分二分类和多分类,XGBoost均可胜任,二分类问题中XGBoost采用 sigmoid 函数将累加值映射为0~1之间,其值代表二分类结果的概率;多分类问题中,采用 softmax 函数将多分类预测值映射到0~1之间,代表样本属于该类别的概率;排序问题暂不讨论。
1.3模型原理:串行方法、加法模型
具体后文 < 3.6如何生成一个XGBoost模型 > 描述,最终模型如下,其中
f
t
(
x
)
f_t(x)
ft(x) 为基函数(模型是线性回归或回归树)
y
^
i
(
t
)
=
∑
t
=
1
t
η
f
t
(
x
i
)
\widehat{y}_i^{(t)}=\displaystyle\sum_{t=1}^{t} \eta f_t(x_i)
y
i(t)=t=1∑tηft(xi)
接下来详细介绍XGBoost算法,首先什么是集成学习?
二.集成学习及主要方法
集成学习(ensemble learning)通过将多个学习器进行组合来完成学习任务。下图显示集成学习的一般结构(取自周志华老师的西瓜书),个体学习器通常由一种现有的学习算法从训练数据产生,例如决策树(C4.5、CART)、BP神经网络等。集成中只包含同种类型的个体学习器时,集成是同质的,同质集成中的个体学习器也称为“基学习器”,相应学习算法称为“基学习器算法”;集成中包含不同类型的个体学习器时,例如既有决策树又有神经网络,这样的集成是异质的,异质集成中个体学习器由不同学习算法生成,这时不再有基学习器算法,相应的个体学习器一般不称为基学习器,直接称为“个体学习器”或“组件学习器”。
集成学习算法需要关注的两个问题,是探索集成学习的关键:
1)个体学习器如何训练得到
例如Adaboost改变训练数据权值;Gradient Boosting的梯度提升
2)如何将个体学习器组合
例如Bagging的投票法——软投票、硬投票;Boosting的线性组合——加法模型
不同的个体学习器训练方法+不同的个体学习器组合=不同的集成学习算法
2.1Boosting 串行方法
Boosting是将弱学习算法提升为强学习算法的机器学习方法,采用加法模型(即基函数的线性组合)与前向分步算法or梯度提升算法。通俗解释:Boosting会训练一系列弱分类器,并将所有学习器的预测结果组合起来作为最终预测结果,在学习过程中,后期的学习器更关注先前学习器学习中的错误。
-
典型算法
Adaboost、GBDT、XGBoost、LightGBM等,其中AdaBoost继承了Boosting的思想,为每个弱学习器赋予不同权值,将所有弱分类器权重和作为预测的结果,达到强学习器的效果;Gradient Boosting是Boosting思想的另一种实现方法,它将损失函数梯度下降的方向作为优化的目标,新的学习器建立在之前学习器损失函数梯度下降的方向,在梯度下降的方向不断优化,使损失函数持续下降,从而提高模型的拟合程度,代表算法GBDT、XGBoost、LightGBM;GBDT(Gradient Tree Boosting,别名 GBM、GBRT、MART)是Gradient Boosting的一种实现,GBDT相较BDT(提升树)基学习器都是采用CART回归树,但BDT是不断拟合残差来优化目标函数,GBDT是通过负梯度近似残差来优化目标函数(即损失函数);XGBoost和LightGBM都是GBDT的改进模型,最终这两个模型成为了集大成者,适合于分类、回归、排序等问题(多种基学习器);支持分布式并行计算(Rabit),具有高可移植性(XGBoost4J-Spark、XGBoost4J-Flink);支持GPU算法加速;结果也更加精准(目标函数用二阶泰勒展开近似);泛化能力更强(加入了结构误差项——正则化降低模型复杂度)。 -
算法特点
Boosting可以有效提高模型准确性,但各个基学习器间存在强依赖关系,只能【串行】生成的序列化方法,时间开销较大(XGBoost和LightGBM在这方面已经做了极大的改进)
2.2Bagging 并行方法
Bagging对数据集进行有放回采样,得到每个基模型所需要的子训练集,然后对所有基模型预测结果进行综合,产生最终的预测结果。对于分类问题,采用投票法(软投票、硬投票)计算结果;对于回归问题,采用平均法计算结果。
- 典型算法
Random Forests随机森林(简称RF)是Bagging最具代表性的算法,基学习器采用决策树,并且在Bagging样本扰动(行采样)的基础上增加了属性扰动(列采样),进一步丰富了样本的多样性。 - 算法特点
Bagging模型的精度要比Boosting低,但各个基学习器相互独立,不存在强依赖关系,可以【并行】生成的序列化方法,时间开销较小(RF模型仅采用决策树作为基模型,进一步优化可训练效率)
2.3Stacking 融合方法
Stacking是通过训练集训练好所有的基模型,然后用基模型的预测结果生成一个新的数据,作为组合器模型的输入,用以训练组合器模型,最终得到预测结果。组合器模型通常采用逻辑回归。
- 算法特点
Stacking一般采用异质集成,即使用多种学习算法训练不同种类的个体学习器。而Boosing和Bagging采用同质集成,即基学习器为同一种基学习算法。
三.XGBoost模型 、目标函数、算法
3.1模型:加法模型
XGBoost同其他的Boosting模型一样,都是加法模型。通俗理解:假设基模型为CART回归树【注释2】模型(即'booster'='gbtree'
),XGBoost训练了一系列二叉树分类器,每个分类器都有至少2个叶子节点,叶子节点权值即为回归树的预测结果,样本在多个分类器落入的叶子节点权值相加,即为模型最终的预测结果得分。依据任务不同得分的后续处理也不同,例如二分类任务最终得分会使用Sigmoid函数映射到[0,1]的值进而完成预测任务(具体的过程以及多分类、回归的转换方式会在后续章节详细解释)。
-
引用论文来解释
论文中加法模型公式表达如下公式(1),K个 f ( x i ) f(x_i) f(xi)模型结果相加即为预测值 y ^ i \widehat{y}_i y i。
-
加法模型(additive model)性质来解释
加法模型公式表达为 f ( x ) = ∑ i = 1 n β m b ( x ; γ m ) f(x)=\displaystyle\sum_{i=1}^{n} \beta_mb(x;\gamma_m) f(x)=i=1∑nβmb(x;γm) ,其中 b ( x ; γ m ) b(x;\gamma_m) b(x;γm) 为基函数【注释3】, γ m \gamma_m γm 为基函数的参数, β m \beta_m βm 为基函数的系数【注释1】。对比论文公式(1),使用时通常会对 f ( x i ) f(x_i) f(xi) 增加缩减系数,即可理解为 β m f ( x i ) \beta_mf(x_i) βmf(xi),可见论文公式(1)是一个加法模型。
-
Booster参数
XGBoost提供3种模型参数可选——gbtree、dart、gblinear,其中gbtree是CART回归树,且最为常用,后文若无特殊说明皆以"booster": "gbtree"做解释说明;dart也是树模型,借鉴了深度神经网络的dropout技术防止过拟合;gblinear为线性模型,采用Elastic Net回归和并行坐标下降法实现。
内容解释:
【注释1】缩减系数:缩减是为了防止过拟合,从而提高模型的泛化能力。缩减会为每一轮训练的新模型增加一个“学习率”,作为系数控制“步长”,进而减小单个基学习器对模型的贡献。
【注释2】CART为二叉树,有分类树也有回归树,XGBoost只使用回归树。
【注释3】加法模型的基函数即为模型的基分类器,Gradient Boosting通常采用CART回归树作为基分类器。
3.2目标函数:损失函数+正则项
目标函数为模型训练提供了优化方向,机器学习中通常使用损失函数做为目标函数,拟合目标为“残差”最小化(残差=预测值-真实值),使得模型预测结果逐步逼近真实值(残差越小,损失越小,模型越好)。
-
引用论文来解释
论文中(2) L ( ϕ L(\phi L(ϕ) 是XGBoost目标函数的表达,通常命名为 O b j Obj Obj,第一项是 l l l(预测值 y ^ i \widehat{y}_i y i,真实值 y i y_i yi)和的损失函数,用于评估模型预测值与真实值之间的误差或损失;第二项是正则化项,用来控制模型复杂度,正则化倾向于选择简单的模型,避免过拟合。也有文章中称第一项为为经验损失\经验风险,第二项为结构化损失\结构化风险。
-
Objective参数
XGBoost中可选的损失函数较多,由objective参数控制,主要包括:
二分类:binary:logistic和binary:logitraw。binary:logistic返回sigmoid(权值之和)
得到0~1之间的值,作为预测概率;binary:logitraw结果不做转换,为预测的原始值。
多分类:multi:softprob和multi:softmax
回归:reg:linear、reg:logistic、reg:poisson、reg:gamma和reg:tweedie。reg:linear通过最小二乘法对模型进行拟合,基于均方差最小化对模型求解。
排序:rank:ndcg -
损失函数的选择依据
XGBoost引入二阶泰勒展开近似和简化目标函数,并通过一阶梯度统计和二阶梯度统计来表示,所以XGBoost的损失函数(公式(2)的第一项)必须是可微分的凸函数,而且需满足二次可微条件。(关于损失函数Objective这里仅做简单说明,后续文章会详细说明)
3.3优化方法:梯度提升算法
Adaboost和提升树(BDT)均采用加法模型和前向分布算法,Adaboost的损失函数为指数函数,提升树的损失函数为平方误差函数。当损失函数是平方误差损失和指数损失函数时,每一步优化是简单的。但更多的机器学习算法使用的损失函数为2.2节Objective参数列举的那样,对这些损失函数(通常统称为一般函数)往往每一步优化并不容易,针对这一问题Freidman提出了梯度提升算法。梯度提升算法关键是利用函数的负梯度在当前模型的值 − [ ∂ L ( y , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f t − 1 ( x ) \ - \bigg [ \frac{\partial{L}(y,f(x_i))}{\partial{f}(x_i)} \bigg ]_{f(x)=f_{t-1}(x)} −[∂f(xi)∂L(y,f(xi))]f(x)=ft−1(x)作为回归问题提升树中的残差的近似值,拟合一个回归树。
先来解释Gradient Boosting的梯度下降
前文提到Gradient Boosting是Boosting算法的另外一种实现,它将损失函数梯度下降方向作为优化目标。将损失函数负梯度的值作为残差,对于平方损失函数(
L
(
y
,
f
(
x
)
)
=
1
2
(
y
−
f
(
x
)
)
2
L(y,f(x))=\frac{1}{2}(y-f(x))^2
L(y,f(x))=21(y−f(x))2)来说,损失函数负梯度的值就是残差
−
∂
L
(
y
,
f
(
x
)
)
∂
f
(
x
)
=
−
1
2
(
2
f
(
x
)
−
2
y
)
=
y
−
f
(
x
)
\ - \frac{\partial{L}(y,f(x))}{\partial{f}(x)} =-\frac{1}{2}(2f(x)-2y)=y-f(x)
−∂f(x)∂L(y,f(x))=−21(2f(x)−2y)=y−f(x)下方
L
(
y
,
f
(
x
)
)
L(y,f(x))
L(y,f(x))的内容不太严谨,自己推的方便解释XGBoost二阶梯度的,没有教材上这样写过,这段就当写给自己留个标记吧
当拟合残差变成拟合负梯度的值(一阶梯度统计用
f
′
(
x
)
f'(x)
f′(x) 来表示,下降的步长用
△
x
\triangle x
△x 来表示),模型增加一个拟合“残差”的新函数
h
t
(
x
)
h_{t}(x)
ht(x) 时
f
t
(
x
)
=
f
t
−
1
(
x
)
+
h
t
(
x
)
f_t(x)=f_{t-1}(x)+h_{t}(x)
ft(x)=ft−1(x)+ht(x)
L
(
y
,
f
(
x
)
)
=
l
(
y
,
f
t
−
1
(
x
)
+
h
t
)
=
l
(
y
,
y
^
(
t
−
1
)
)
+
f
′
(
x
)
△
x
L(y,f(x))=l(y,f_{t-1}(x)+h_t)=l(y,\widehat{y}^{(t-1)})+f'(x)\triangle x
L(y,f(x))=l(y,ft−1(x)+ht)=l(y,y
(t−1))+f′(x)△xGBDT也是引用了一阶梯度(泰勒一阶展开),不同之处在于GBDT以CART回归树为子模型
接下来,引用论文做公式推导来解释XGBoost
论文公式(2)中的集成模型无法在欧氏空间中使用传统的优化方法进行优化。模型是用相加的方式训练的,让
y
^
i
(
t
)
\widehat{y}_i^{(t)}
y
i(t) 为第
i
i
i 个实例在第
t
t
t 次迭代时的预测,我们需要添加
f
t
f_t
ft 来最小化目标。
y
^
i
(
t
)
=
y
^
i
(
t
−
1
)
+
f
t
(
x
i
)
\widehat{y}_i^{(t)}=\widehat{y}_i^{(t-1)}+f_t(x_i)
y
i(t)=y
i(t−1)+ft(xi) 其中
y
^
i
(
t
−
1
)
\widehat{y}_i^{(t-1)}
y
i(t−1) 是前面
t
−
1
t-1
t−1 个模型【注释4】的预测结果(已经是一个常数固定值),
f
t
(
x
i
)
f_t(x_i)
ft(xi)是当前第
t
t
t 个模型的预测结果。改进公式(2)可得如下公式
利用贪心算法添加对模型改进最大的
f
t
f_t
ft 。梯度提升算法中二阶近似可以用来快速优化目标。
补充内容:
泰勒公式定义:泰勒公式是一个用函数某点信息描述其附近取值的公式。
一元泰勒公式的一般形式,
f
(
x
)
f(x)
f(x)称为
n
n
n 阶泰勒公式:
f
(
x
)
=
f
(
x
0
)
+
f
′
(
x
0
)
1
!
(
x
−
x
0
)
+
f
′
′
(
x
0
)
2
!
(
x
−
x
0
)
2
+
.
.
.
+
f
(
n
)
(
x
0
)
n
!
(
x
−
x
0
)
n
+
R
n
(
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)
f(x)=f(x0)+1!f′(x0)(x−x0)+2!f′′(x0)(x−x0)2+...+n!f(n)(x0)(x−x0)n+Rn(x)
其中,
P
(
x
)
=
f
(
x
0
)
+
f
′
(
x
0
)
1
!
(
x
−
x
0
)
+
f
′
′
(
x
0
)
2
!
(
x
−
x
0
)
2
+
.
.
.
+
f
(
n
)
(
x
0
)
n
!
(
x
−
x
0
)
n
P(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
P(x)=f(x0)+1!f′(x0)(x−x0)+2!f′′(x0)(x−x0)2+...+n!f(n)(x0)(x−x0)n 称为
n
n
n 次泰勒多项式,
P
(
x
)
P(x)
P(x) 与
f
(
x
)
f(x)
f(x) 的误差
R
n
(
x
)
R_n(x)
Rn(x) 称为
n
n
n 阶泰勒余项。
根据上述泰勒公式的定义可知,如果函数曲线足够平滑,则可通过某一点的各阶导数值构建一个多项式来近似表示函数在该点邻域的值。XGBoost只取泰勒二阶展开,定义如下:
f
(
x
+
△
x
)
=
~
f
(
x
)
+
f
′
(
x
)
△
x
+
1
2
f
′
′
(
x
)
△
x
2
f(x+ \triangle x) \tilde = f(x)+f'(x)\triangle x + \frac{1}{2}f''(x)\triangle x^2
f(x+△x)=~f(x)+f′(x)△x+21f′′(x)△x2
将改进后的公式(2)中
y
^
i
(
t
−
1
)
\widehat{y}_i^{(t-1)}
y
i(t−1) 看做
f
(
x
)
f(x)
f(x),将
f
t
(
x
i
)
f_t(x_i)
ft(xi) 看做
△
x
\triangle x
△x ,即可对XGBoost目标函数进行如下泰勒展开:
其中
g
i
g_i
gi 为损失函数一阶梯度的度量,
h
i
h_i
hi 为损失函数二阶梯度的度量。
去掉公式中的常数项,在第
t
t
t 步得到以下简化的目标函数
公式(3)是在样本的角度进行目标函数的拟合,样本数量n。当从叶子节点的角度考虑时,同样适用如下公式(4)的转换,n个样本均会落入该树的叶子节点,无非是将n个样本的扫描顺序改变了,变成了T颗树中各叶子节点样本的扫描。
公式(4)中一阶梯度
g
i
g_i
gi 、二阶梯度
h
i
h_i
hi 随着样本确定其对应梯度就已经确定了,
λ
\lambda
λ 和
γ
\gamma
γ 都是需要人为指定的超参数【注释6】。因此求目标函数
L
~
(
t
)
\widetilde{L}^{(t)}
L
(t) 的最小值就变成了简单的一元二次方程
w
j
w_j
wj求最小值的问题了,
w
j
w_j
wj 是叶子节点权值和。
∂
L
~
(
t
)
∂
w
j
=
0
\frac{\partial\widetilde{L}^{(t)}}{\partial w_j}=0
∂wj∂L
(t)=0即可得到公式(5)
公式(5)的结果带回公式(4)可得目标函数极小值得公式(6)
以论文中下图为例,即为目标函数Obj的表达形式,其中
G
j
G_j
Gj 为叶子节点内各样本的一阶梯度
g
g
g 的加和,即
G
j
G_j
Gj 为叶子节点内样本一阶梯度的和;
H
j
H_j
Hj 同理;图中树有3个叶子节点,所以叶子节点个数
T
T
T=3。
至此,求目标函数最小值min(obj)
问题,已经变成了样本一阶梯度and二阶梯度的组合方式问题,XGBoost采用梯度提升算法【注释5】,沿着梯度的反方向优化目标函数,使损失函数极小化,这点也已经解释清楚了。
内容解释:
【注释4】t-1个模型:当基模型为树模型时,就是第 t-1 颗树
【注释5】有其他课程讲解XGBoost采用前向分布算法,但通过实际理解和李航老师《机器学习方法》8.4.3梯度提升讲解,可以证明XGBoost使用的是梯度学习算法,并非前向分布算法,这里容易被误导。
【注释6】模型参数一般分两类:一类是可以通过学习获得的参数;另一类是在开始学习过程中设定的参数,而没办法通过训练得到的,这类参数就是超参数。
3.4树生成方法:启发式算法
公式(6)可以作为一个评分函数来衡量树形结构的质量。这个分数类似于评价决策树的杂质分数,只是它是针对更广泛的目标函数推导出来的。通常情况下,不可能列举出所有可能的树结构。取而代之的是贪心算法【注释8】,从单个叶子开始,迭代地向树中添加分支。即先从树的根节点开始,计算节点分类后比分裂前目标函数值是否减少。
引用论文做公式推导来解释
假设【注释9】 I L I_L IL 和 I R I_R IR 是分裂后左节点和右节点的数据集,令 I I I= I L I_L IL∪ I R I_R IR,那么分割后的损失减少如公式(7)。 I I I 、 I L I_L IL、 I R I_R IR 分别带入公式(6), L s p l i t L_{split} Lsplit = O b j I Obj_I ObjI - ( O b j L Obj_L ObjL + O b j R Obj_R ObjR)
则最终可得到节点分裂的目标函数如公式(7),选出最大的
L
s
p
l
i
t
L_{split}
Lsplit【注释7】,即可找到最优特征和最优切分点。
公式整理简化和说明,后文所说公式(7)皆为下面公式:
O
b
j
s
p
l
i
t
=
1
2
[
G
L
2
H
L
+
λ
+
G
R
2
H
R
+
λ
−
G
2
H
+
λ
)
]
−
γ
(
7
)
Obj_{split}=\frac{1}{2}\bigg [ \frac{G_L^2}{H_L+ \lambda}+\frac{G_R^2}{H_R+ \lambda}-\frac{G^2}{H+ \lambda}) \bigg ] - \gamma \qquad(7)
Objsplit=21[HL+λGL2+HR+λGR2−H+λG2)]−γ(7)
其中,
G
R
=
G
−
G
L
G_R=G-G_L
GR=G−GL ,
H
R
=
H
−
H
L
H_R=H-H_L
HR=H−HL,进一步提高了计算效率。
公式(7)前部分是
G
a
i
n
Gain
Gain 增益,整理后获取max增益Gain的方法如下
G
a
i
n
=
m
a
x
(
g
a
i
n
,
G
L
2
H
L
+
λ
+
G
R
2
H
R
+
λ
−
G
2
H
+
λ
)
Gain=max(gain,\frac{G_L^2}{H_L+ \lambda}+\frac{G_R^2}{H_R+ \lambda}-\frac{G^2}{H+ \lambda})
Gain=max(gain,HL+λGL2+HR+λGR2−H+λG2)
后部分的
γ
\gamma
γ ,即模型中参数gamma,代表树叶子节点进一步分裂所需的最小损失减少量,即树叶子节点分裂所需的最小增益。总不能让 损失函数
O
b
j
s
p
l
i
t
Obj_{split}
Objsplit < 0吧!这也是XGBoost所采用的剪枝方法,即判断当前节点的收益
G
a
i
n
Gain
Gain 是否小于定义的最小收益
γ
\gamma
γ ,若比最小收益小,则进行剪枝。相较CART树的剪枝,XGBoost的剪枝方法更简单、更高效。
内容解释:
【注释7】
L
s
p
l
i
t
L_{split}
Lsplit 即
O
b
j
s
p
l
i
t
Obj_{split}
Objsplit,是一个意思
【注释8】贪心算法是一种启发式算法,只考虑当前最优的策略,而非全局最优的策略
【注释9】基模型CART树是二叉树,所以只有
I
L
I_L
IL 和
I
R
I_R
IR 成立,且此时T=2成立
3.5集成多样性:列采样、行采样
-
集成多样性的重要性
集成多样性,即个体学习器之间的差异,是集成学习方法的重要议题。简而言之,如果结合完全相同的个体学习器,显然不会有准确率提升;想要结合之后准确率提升,个体学习器之间必须有差异。个体学习器应当兼具精确性与多样性,正因为“互补性”比单纯的精度更重要,结合高精度的个体学期经常比结合相对稍弱个体学习器的性能更差。集成学习的成功依赖于个体学习器精度and多样性之间的均衡。个体学习器的精度和多样性此消彼长 -
集成多样性的作用
由上述可知集成多样性是要降低个体学习器的精度,防止整体模型过拟合。XGBoost除了采用了 正则项 Ω ( f k ) \Omega(f_k) Ω(fk) 和 缩减系数 η \eta η 之外,还借鉴了RF随机森林的 样本扰动和属性扰动(即行采样和列采样) 保障个体学习器的多样性,达到防止模型过拟合的目的。 -
模型参数
subsample:训练样本的采样率,根据值做随机采样,参数范围(0,1],常用值为0.5~1
colsample_bytree:构建树时对列进行采样,根据值做随机采样,参数范围(0,1],常用值为0.5~1
根据实践经验,列采样比行采样更能有效防止模型过拟合。而且,列子样本的使用也加快了后面描述的并行算法的计算速度。
3.6如何生成一个XGBoost模型
通过上述内容,对XGBoost的训练过程进行简单概括:
1
◯
\normalsize{\textcircled{\scriptsize{1}}}\normalsize\enspace
1◯ 每轮训练增加一个新的树模型(行列采样得到新的数据集,模型多样性)
2
◯
\normalsize{\textcircled{\scriptsize{2}}}\normalsize\enspace
2◯ 在每轮训练开始,首先计算梯度统计:
g
i
=
∂
L
(
y
i
,
y
^
(
t
−
1
)
)
∂
y
^
(
t
−
1
)
g_i=\frac{\partial{L}(y_i,\widehat{y}^{(t-1)})}{\partial\widehat{y}^{(t-1)}}
gi=∂y
(t−1)∂L(yi,y
(t−1))
h
i
=
∂
2
L
(
y
i
,
y
^
(
t
−
1
)
)
∂
y
^
(
t
−
1
)
h_i= \frac{\partial^2{L}(y_i,\widehat{y}^{(t-1)})}{\partial\widehat{y}^{(t-1)}}
hi=∂y
(t−1)∂2L(yi,y
(t−1))
3
◯
\normalsize{\textcircled{\scriptsize{3}}}\normalsize\enspace
3◯ 根据贪心算法及梯度统计信息生成一颗完整树
f
t
(
x
)
f_t(x)
ft(x)
- 节点分裂通过如下公式评估,选择最优切分点 O b j s p l i t = 1 2 [ G L 2 H L + λ + G R 2 H R + λ − G 2 H + λ ) ] − γ ( 7 ) Obj_{split}=\frac{1}{2}\bigg [ \frac{G_L^2}{H_L+ \lambda}+\frac{G_R^2}{H_R+ \lambda}-\frac{G^2}{H+ \lambda}) \bigg ] - \gamma \qquad(7) Objsplit=21[HL+λGL2+HR+λGR2−H+λG2)]−γ(7)
- 最终树叶子节点的权重为 w j ∗ = − G j H j + λ w^*_j=- \frac{G_j}{H_j+\lambda} wj∗=−Hj+λGj
4 ◯ \normalsize{\textcircled{\scriptsize{4}}}\normalsize\enspace 4◯ 将新生成的树模型 f t ( x ) f_t(x) ft(x) 加入模型中, η \eta η 为新生成树模型的缩减系数【注释1】,可得预测模型 y ^ i ( t ) = y ^ i ( t − 1 ) + η f t ( x i ) \widehat{y}_i^{(t)}=\widehat{y}_i^{(t-1)}+\eta f_t(x_i) y i(t)=y i(t−1)+ηft(xi)模型整理结果(与3.1的加法模型一致) y ^ i ( t ) = ∑ t = 1 t η f t ( x i ) \widehat{y}_i^{(t)}=\displaystyle\sum_{t=1}^{t} \eta f_t(x_i) y i(t)=t=1∑tηft(xi)
下面是一种猜测,只当作为一种解释写给自己
结合上述XGBoost训练过程来看,并无法直观体现出Boosting串行方法,即无法解释基学习器之间的强关联关系,也就无法区别于Bagging的基学习器训练过程,即无法说明基模型训练不能并行所带来的训练效率问题。为这一连串的“无法”找个解释,假设XGBoost的n_estimators=50
即最终模型由50颗树组成的,但模型训练过程中可能训练了1000颗树,才找到了可以加在一起满足损失函数持续减小的50颗树。训练过程中其余的950颗树也训练出来了,不过增加后损失函数不降反增,所以被剪去了,至此贪心的完成了优胜略汰的过程。所以XGBoost依然是串行方法,基学习器之间依然有强关联关系。
顺便提一句,提前停止策略(这个不是猜想了):
1)训练迭代次数完成,例如上例迭代50次,迭代完成则模型训练停止
2)最小损失,当模型最终的损失
L
(
t
)
L^{(t)}
L(t) 小于某一设定值时,模型停止训练,即使模型没有是否达到最大迭代次数,即上例未迭代到第50个基模型,模型便训练完成了,最后的基学习器可能只有1~50的任何数量个。
接下来基于上述推导所得的增益 G a i n Gain Gain,来看看XGBoost又是如何生成个体学习器的
四.XGBoost生成新树的过程
XGBoost每轮训练生成新的树模型时,首先计算所有特征在所有切分点分裂前后的 L s p l i t L_{split} Lsplit( 即 O b j s p l i t 即Obj_{split} 即Objsplit),然后选取 O b j s p l i t Obj_{split} Objsplit 最大的特征及其切分点作为最优特征和最优切分点。XGBoost提供了多种最优特征和最优切分点的查找算法,统称为切分点查找算法,包括精确贪心算法、近似算法等。值得一提的是,所有的切分点查找算法都是贪心算法,所以符合3.4中启发式算法的要求。
依然引用论文来解释
先说结论,解释论文中下图,希格斯玻色子10M数据集采用不同 切分点查找算法 对应的 AUC值收敛曲线(验证集AUC值 和 迭代次数)
1)exact greedy:采用所有切分点迭代的精确贪心算法;
2)global eps=0.3:采用分桶方式选择切分点的近似算法的全局策略,eps越小 特征值分桶越多 切分点越多,模型训练越慢。该条曲线可知,全局策略eps=0.3时模型AUC收敛效果低于其他几种方式;
3)local eps=0.3:近似算法的本地策略,eps=0.3时即可获得较好的AUC收敛效果,所以该策略是时间与效率选择的最佳方案;
4)global eps=0.05:近似算法的全局策略,当eps=0.05,切分点比eps=0.3时会多出6倍时,模型AUC收敛效果会与精确贪心算法相似。
结论:通过精确贪心算法和近似算法的比较,采用分桶方式选择切分点的近似算法本地策略,可以很好的兼顾模型的效率和拟合效果,模型训练的又快又好。全局策略需要更细的分桶才能达到本地策略的精确度,但全局策略在选取候选切分点集合时比本地策略更简单。
4.1精确贪心算法
树学习的关键问题之一是找到最好的分割,如公式(7)所示。为了做到这一点,分割查找算法枚举所有特征上的所有可能的分割,一 一求得其 O b j s p l i t Obj_{split} Objsplit ,然后选择 m a x ( O b j s p l i t ) max(Obj_{split}) max(Objsplit) 的特征及对应切分点作为最优特征和最优切分点,我们称之为精确贪心算法。
XGBoost的单机版本支持精确贪婪算法。枚举连续特征的所有可能分割是需要计算的,为了高效地完成这一任务,算法必须首先根据特征值对数据进行排序,并按排序顺序访问数据,积累公式(7)中结构得分的梯度统计量 G 、 H G、H G、H。最终返回 m a x ( s c o r e ) max(score) max(score)值。
算法实现步骤如论文下图:
\qquad
简单描述图中算法内容:
\qquad
输入:
I
I
I,模型树当前条件节点的实例集
\qquad
输入:
d
d
d,特征维度
\qquad
初始化
g
a
i
n
=
0
gain=0
gain=0,
G
=
∑
i
∈
I
g
i
G=\sum_{i\in I}g_i
G=∑i∈Igi,
H
=
∑
i
∈
I
h
i
H=\sum_{i\in I}h_i
H=∑i∈Ihi
\qquad
对每个特征
k
=
1
,
2
,
.
.
.
m
k=1,2,...m
k=1,2,...m,执行遍历操作
\qquad \qquad
初始化
G
L
=
0
G_L=0
GL=0,
H
L
=
0
H_L=0
HL=0
\qquad \qquad
对条件节点包含的所有样本在该特征下的取值进行排序
s
o
r
t
e
d
(
I
,
b
y
X
j
k
)
sorted(I,by X_{jk})
sorted(I,byXjk),并遍历每个取值
j
j
j
\qquad \qquad \qquad
计算左子节点的梯度统计
G
L
=
G
L
+
g
j
G_L=G_L+g_j
GL=GL+gj,
H
L
=
H
L
+
h
j
H_L=H_L+h_j
HL=HL+hj
\qquad \qquad \qquad
计算右子节点的梯度统计
G
R
=
G
−
G
L
G_R=G - G_L
GR=G−GL,
H
R
=
H
−
H
L
H_R=H - H_L
HR=H−HL
\qquad \qquad \qquad
计算
s
c
o
r
e
score
score 值,max(gain)
\qquad \qquad
特征取值
j
j
j 遍历结束
\qquad
特征数
k
k
k遍历结束
\qquad
输出:最大收益的特征及其切分点
4.2近似算法
精确贪心算法在选择最优特征和最优切分点时是一种十分有效的方法,但当数据不能完全加载到内存时,该算法会变得非常低效,算法在计算过程中需要不断在内存与磁盘之间进行数据交换,即使在分布式环境中也同样存在这个问题。为了更高效的选择最优特征及切分点,XGBoost还有一种近似算法来解决这个问题,也有称之为基于直方图的近似算法。
近似算法的主要思想是:对某一特征寻找最优切分点时,首先对该特征的所有切分点按分位数分桶,得到一个候选切分点集。该算法有两种构建策略:全局策略和本地策略。
- 全局策略:在树构建的初识阶段对每一个特征确定一个候选切分点集合,并在该树每一层的节点分裂中均采用此集合计算收益,整个过程中候选切分点集合不改变。
- 本地策略:在每一次节点分裂时均重新确定候选切分点。
算法实现步骤如论文下图:
\qquad
简单描述图中算法内容:
\qquad
对每个特征
k
=
1
,
2
,
.
.
.
m
k=1,2,...m
k=1,2,...m,执行遍历操作
\qquad \qquad
按分位数对特征分桶
l
l
l 个
\qquad \qquad
方案可以应用于每棵树(全局策略),也可以是每一个条件节点(本地策略)。
\qquad
特征数
k
k
k遍历结束
\qquad
对每个特征
k
=
1
,
2
,
.
.
.
m
k=1,2,...m
k=1,2,...m,执行遍历操作
\qquad \qquad
依据分桶切分点计算
G
G
G
\qquad \qquad
依据分桶切分点计算
H
H
H
\qquad
特征数
k
k
k遍历结束
\qquad
按照与精确贪心算法相同的步骤找到
m
a
x
max
max
\qquad
返回最大增益的候选切分点
全局策略需要更细的分桶才能达到本地策略的精确度,但全局策略在选取候选切分点集合时比本地策略更简单。在XGBoost系统中,可以自由选择使用精确贪心算法、近似算法全局策略、近似算法本地策略。在 sklearn的版本中目前只找到了max_bin
参数,用于指定使用基于直方图的算法,每个特征的最大箱数。这里的基于直方图算法就是本节所说的近似算法。
4.3加权分位算法
略
4.4稀疏感知切分点查找算法
略
4.5快速直方图算法
该算法借鉴LightGBM
附言
附言1:希腊字母
文中希腊字母,以及在模型中所代表的含义
β
\beta
β —— beta 加法模型的系数,XGBoost中就是
η
\eta
η
η
\eta
η —— eta 树模型更新时缩减的步长,别名learning_rate,即学习率
Ω
\Omega
Ω —— Omega 正则项
γ
\gamma
γ —— gamma 树叶子节点分裂所需的最小增益
λ
\lambda
λ —— lambda 节点权重
w
w
w的惩罚系数
Δ
\Delta
Δ —— Delta 文中
Δ
x
\Delta x
Δx表示
f
t
(
x
i
)
f_t(x_i)
ft(xi)
ε
\varepsilon
ε —— epsilon
附言2:相关推荐
1.关于XGBoost的应用示例,
见《XGBoost模型调参、训练、评估、保存和预测》 ,包含模型脚本文件;
2.关于分类任务的评估指标值详解,
见《分类任务评估1——推导sklearn分类任务评估指标》,其中包含了详细的推理过程;
见《分类任务评估2——推导ROC曲线、P-R曲线和K-S曲线》,其中包含ROC曲线、P-R曲线和K-S曲线的推导与绘制;
3.关于XGBoost模型中树的绘制和模型理解,
见《Graphviz绘制模型树1——软件配置与XGBoost树的绘制》,包含Graphviz软件的安装和配置,以及to_graphviz()和plot_trees()两个画图函数的部分使用细节;
见《Graphviz绘制模型树2——XGBoost模型的可解释性》,从模型中的树着手解释XGBoost模型,并用EXCEL构建出模型。
4.关于XGBoost实践,
见《机器学习实践(1.1)XGBoost分类任务》,包含二分类、多分类任务以及多分类的评估方法。
见《机器学习实践(1.2)XGBoost回归任务》,包含回归任务模型训练、评估(R2、MSE)。
❤️ 机器学习内容持续更新中… ❤️
声明:本文所载信息不保证准确性和完整性。文中所述内容和意见仅供参考,不构成实际商业建议,可收藏可转发但请勿转载,如有雷同纯属巧合。