一、Boosting思想
Boosting方法训练基分类器时采用串行的方式,各个基分类器之间有依赖。它的基本思路是将基分类器层层叠加,每一层在训练的时候,对前一层基分类器分错的样本,给予更高的权重。测试时,根据各层分类器的结果的加权得到最终结果。
Bagging与Boosting的串行训练方式不同,Bagging方法在训练过程中,各基分类器之间无强依赖,可以进行并行训练。
二、什么是XGBoost?
XGBoost(Exterme Gradient Boosting极限梯度提升)是基于决策树的集成机器学习算法,它以梯度提升(Gradient Boost)为框架。
XGBoost是由由GBDT发展而来,同样是利用加法模型与前向分步算法实现学习的优化过程。
在GBDT的整体的框架上修改了损失函数,从原来的使用负梯度也就是一阶导的负,到使用一阶导和二阶导。
三、XGBoost与GBDT的区别
- 优化方法:GBDT优化时只使用了一阶导数信息,XGBoost在优化时使用了一、二阶导数信息。
- 目标函数:XGBoost的损失函数添加了正则化项,使用正则用以控制模型的复杂度,正则项里包含了树的叶子节点个数、每个叶子节点权重(叶结点的socre值)的平方和。
- 缺失值处理:XBGoost对缺失值进行了处理,通过学习模型自动选择最优的缺失值默认切分方向。
- 防止过拟合: XGBoost除了增加了正则项来防止过拟合,还支持行列采样的方式来防止过拟合。
四、XGBoost的基分类器
XGBoost的可以使用Regression Tree(CART)作为基学习器,也可以使用线性分类器作为基学习器。以CART作为基学习器时,其决策规则和决策树是一样的,但CART的每一个叶节点具有一个权重,也就是叶节点的得分或者说是叶节点的预测值。
CART的示例:要预测一家人对电子游戏的喜好程度,考虑到年轻和年老相比,年轻更可能喜欢电子游戏,以及男性和女性相比,男性更喜欢电子游戏,故先根据年龄大小区分小孩和大人,然后再通过性别区分开是男是女,逐一给各人在电子游戏喜好程度上打分,如下图所示
图中为两颗回归树(左右两个),其中树下方的输出值即为叶节点的权重(得分),当输出一个样本进行预测时,根据每个内部节点的决策条件进行划分节点,最终被划分到的叶节点的权重即为该样本的预测输出值。
五、模型的学习
XGBoost模型的定义为:给定一个包含n个样本的数据集,
∣ D ∣ = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x n , y n ) } \left| D \right|=\left\{ \left( x_{1},y_{1} \right), \left( x_{2},y_{2} \right),...,\left( x_{n},y_{n} \right)\right\} ∣D∣={(x1,y1),(x2,y2),...,(xn,yn)}
集成模型的预测输出表示为:
y ^ i = ϕ ( x i ) = ∑ k = 1 K f k ( x i ) \hat y_{i}=\phi\left( x_{i} \right)=\sum_{k=1}^{K}{f_{k}\left( x_{i} \right)} y^i=ϕ(xi)=∑k=1Kfk(xi) (1)
其中, f k f_{k} fk表示回归树,K为回归树的数量。整个式 (1) 表示给定一个输入 x i x_{i} xi,输出值为 K颗回归树得预测值(即按照相应回归树的决策规则,所划分到的叶节点的权重)相加。
1、定义目标函数,即损失函数以及正则项。
L ( ϕ ) = ∑ i l ( y ^ i , y i ) + ∑ k Ω ( f k ) L\left( \phi \right)=\sum_{i}{l\left( \hat y_{i} ,y_{i}\right)}+\sum_{k}{\Omega\left( f_{k} \right)} L(ϕ)=∑il(y^i,yi)+∑kΩ(fk) (2)
其中
Ω
(
f
)
=
Υ
T
+
1
2
λ
∣
∣
w
∣
∣
2
\Omega\left( f \right)=\Upsilon T+\frac{1}{2}\lambda ||w||^2
Ω(f)=ΥT+21λ∣∣w∣∣2
公式 (2) 第一部分是度量预测值与真实值之间的损失函数,第二部分表示对模型复杂度的惩罚项(正则项),在惩罚项中γ、λ表示惩罚系数,T表示给定一颗树的叶节点数, ∣ ∣ w ∣ ∣ 2 ||w||^2 ∣∣w∣∣2表示每颗树叶节点上的输出分数的平方(相当于L2正则)。从目标函数的定义可以看出XGBoost对模型复杂度考虑了每颗树的叶节点个数,以及每颗树叶节点输出得分值得平方和。
2、优化目标函数
此处 f k f_{k} fk表示的是一颗树,而非一个数值型的向量,所以不能使用梯度下降的方式去优化该目标函数,应使用前向分步算法优化目标函数。设 y ^ i ( t ) \hat y_{i}^{\left( t \right)} y^i(t)是第i个样本在第t次迭代(第t颗树)的预测值。则
y ^ i ( t ) = y ^ i ( t − 1 ) + f t ( x i ) \hat y_{i}^{\left( t \right)}=\hat y_{i}^{\left( t-1 \right)}+f_{t}\left( x_{i} \right) y^i(t)=y^i(t−1)+ft(xi) (3)
公式 (3) 表示样本 i 在 t 次迭代后的预测值 = 样本 i 在前 t-1 次迭代后的预测值 + 当前第t颗树预测值。则目标函数可以表示为:
L ( t ) = ∑ i = 1 n l ( y i , y ^ i ( t ) ) + ∑ i t Ω ( f i ) = ∑ i = 1 n l ( y i , y ^ i ( t − 1 ) + f t ( x i ) ) + Ω ( f t ) + c o n s t a n t L^{\left( t \right)}=\sum_{i=1}^{n}{l\left(y_{i} ,\hat y_{i}^{\left( t \right)}\right)}+\sum_{i}^{t}{\Omega\left( f_{i} \right)} \\ = \sum_{i=1}^{n}{l\left(y_{i} ,\hat y_{i}^{\left( t-1 \right)}+f_{t}(x_{i})\right)}+\Omega\left( f_{t} \right)+constant L(t)=∑i=1nl(yi,y^i(t))+∑itΩ(fi)=∑i=1nl(yi,y^i(t−1)+ft(xi))+Ω(ft)+constant (4)
式 (4) 表示贪心地添加使得模型提升最大的
f
t
f_{t}
ft其中constant表示常数项,这个常数项是指前t-1次迭代的惩罚项为一个常数,即公式中
∑
i
t
Ω
(
f
i
)
\sum_{i}^{t}{\Omega\left( f_{i} \right)}
∑itΩ(fi)部分,在第t次迭代时,前t-1次迭产生的t-1颗树已经完全确定,则t-1颗树的叶节点以及权重都已经确定,所以变成了常数。在 (4) 中如果考虑平方损失函数,则 (4) 可以表示为:
L
t
=
∑
i
=
1
n
(
y
i
−
(
y
^
i
(
t
−
1
)
+
f
t
(
x
i
)
)
)
2
+
Ω
(
f
t
)
+
c
o
n
s
t
a
n
t
=
∑
i
=
1
n
(
y
i
−
y
i
(
t
−
1
)
−
f
t
(
x
i
)
)
2
+
Ω
(
f
t
)
+
c
o
n
s
t
a
n
t
(
式
5
)
L^{t}=\sum_{i=1}^{n}{\left( y_{i} -(\hat y_{i}^{(t-1)}+f_{t}(x_{i}))\right)}^2+\Omega(f_{t})+constant\\=\sum_{i=1}^{n}{(y_{i}-y_{i}^{(t-1)}-f_{t}(x_{i}))}^2+\Omega(f_{t})+constant (式5)
Lt=i=1∑n(yi−(y^i(t−1)+ft(xi)))2+Ω(ft)+constant=i=1∑n(yi−yi(t−1)−ft(xi))2+Ω(ft)+constant(式5)
式5中 y i − y i ( t − 1 ) y_{i}-y_{i}^{(t-1)} yi−yi(t−1)表示残差,即经过前t-1颗树的预测之后与真实值之间的差距,也就是在GBDT中所使用的残差概念。在XGBoost中提出使用二阶泰勒展开式近似表示式5泰勒展开式的二阶形式为:
f ( x + Δ x ) ≃ f ( x ) + f ′ ( x ) Δ x + 1 2 f ′ ′ ( x ) Δ x 2 f(x+\Delta x)\simeq f(x)+f^{'}(x)\Delta x+\frac{1}{2}f^{''}(x)\Delta x^2 f(x+Δx)≃f(x)+f′(x)Δx+21f′′(x)Δx2 (6)
定义 g i = ∂ y ^ ( t − 1 ) l ( y i , y ^ ( t − 1 ) ) , h i = ∂ y ^ i ( t − 1 ) 2 l ( y i , y ^ ( t − 1 ) ) g_{i}=\partial_{\hat y^{(t-1)}}l(y_{i},\hat y^{(t-1)}),h_{i}=\partial_{\hat y_{i}^{(t-1)}}^{2}l(y_{i},\hat y^{(t-1)}) gi=∂y^(t−1)l(yi,y^(t−1)),hi=∂y^i(t−1)2l(yi,y^(t−1))则根据 (6) 可以将 (4) 表示为:
L ( 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 o n s t a n t L^{(t)}\simeq \sum_{i=1}^{n}{[l(y_{i},\hat y_{i}^{(t-1)})+g_{i}f_{t}(x_{i})+\frac{1}{2}h_{i}f_{t}^{2}(x_{i})]}+\Omega(f_{t})+constant L(t)≃∑i=1n[l(yi,y^i(t−1))+gift(xi)+21hift2(xi)]+Ω(ft)+constant (7)
注意 (7) 中 l ( y i , y ^ i ( t − 1 ) ) l(y_{i},\hat y_{i}^{(t-1)}) l(yi,y^i(t−1))表示前t-1次迭代的损失函数,在当前第t次迭代来说已经是一个确定的常数,省略常数项则得到下面的式子:
L ( t ) = ∑ i = 1 n [ g i f t ( x i ) + 1 2 h i f t 2 ( x i ) ] + Ω ( f t ) L^{(t)}= \sum_{i=1}^{n}{[g_{i}f_{t}(x_{i})+\frac{1}{2}h_{i}f_{t}^{2}(x_{i})]}+\Omega(f_{t}) L(t)=∑i=1n[gift(xi)+21hift2(xi)]+Ω(ft) (8)
则我们的目标函数变成了 (8) 可以看出目标函数只依赖于数据点的一阶和二阶导数。其中
g i = ∂ y ^ ( t − 1 ) l ( y i , y ^ ( t − 1 ) ) , h i = ∂ y ^ i ( t − 1 ) 2 l ( y i , y ^ ( t − 1 ) ) g_{i}=\partial_{\hat y^{(t-1)}}l(y_{i},\hat y^{(t-1)}),h_{i}=\partial_{\hat y_{i}^{(t-1)}}^{2}l(y_{i},\hat y^{(t-1)}) gi=∂y^(t−1)l(yi,y^(t−1)),hi=∂y^i(t−1)2l(yi,y^(t−1))
接下来针对公式8进行细分。首先定义集合 [公式]为树的第j个叶节点上的所有样本点的集合,即给定一颗树,所有按照决策规则被划分到第j个叶节点的样本集合。则根据式2中对模型复杂度惩罚项的定义,将其带入式8有:
L
(
t
)
=
∑
i
=
1
n
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
Ω
(
f
t
)
=
∑
i
=
1
n
[
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
(
式
9
)
L^{(t)}= \sum_{i=1}^{n}{[g_{i}f_{t}(x_{i})+\frac{1}{2}h_{i}f_{t}^{2}(x_{i})]}+\Omega(f_{t}) \\= \sum_{i=1}^{n}{[g_{i}f_{t}(x_{i})+\frac{1}{2}h_{i}f_{t}^{2}(x_{i})]}+\Upsilon T+\frac{1}{2}\lambda \sum_{j=1}^{T}{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 (式9)
L(t)=i=1∑n[gift(xi)+21hift2(xi)]+Ω(ft)=i=1∑n[gift(xi)+21hift2(xi)]+ΥT+21λj=1∑Twj2=j=1∑T[(i∈Ij∑gi)wj+21(i∈Ij∑hi+λ)wj2]+γT(式9)
对式9进行求导:
令 ∂ L ( t ) ∂ w j = 0 ⇒ ( ∑ i ∈ I j g i ) + ( ∑ i ∈ I j h i + λ ) w j = 0 ⇒ ( ∑ i ∈ I j h i + λ ) w j = − ∑ i ∈ I j g i ⇒ w j ∗ = − ∑ i ∈ I j g i ∑ i ∈ I j h i + λ ( 式 10 ) 令 \frac{\partial L^{(t)}}{\partial w_{j}}=0 \\\Rightarrow (\sum_{i\in I_{j}} {g_{i})+(\sum_{i\in I_{j}}{h_{i}+\lambda})w_{j}}=0\\\Rightarrow (\sum_{i\in I_{j}}{h_{i}+\lambda})w_{j}=-\sum_{i\in I_{j}}{g_{i}}\\\Rightarrow w_{j}^{*}=-\frac{\sum_{i\in I_{j}}{g_{i}}}{\sum_{i\in I_{j}}{h_{i}+\lambda}} (式10) 令∂wj∂L(t)=0⇒(i∈Ij∑gi)+(i∈Ij∑hi+λ)wj=0⇒(i∈Ij∑hi+λ)wj=−i∈Ij∑gi⇒wj∗=−∑i∈Ijhi+λ∑i∈Ijgi(式10)
将(式10)带入(式9)中得到(式11):
L ( t ) = − 1 2 ∑ j = 1 T ( ∑ i ∈ I j g i ) 2 ∑ i ∈ I j h i + λ + Υ T L^{(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}}}+\Upsilon T L(t)=−21∑j=1T∑i∈Ijhi+λ(∑i∈Ijgi)2+ΥT (11)
令 G i = ∑ i ∈ I j g i , H i = ∑ i ∈ I j h i G_{i}=\sum_{i\in I_{j}}{g_{i}},H_{i}=\sum_{i\in I_{j}}{h_{i}} Gi=∑i∈Ijgi,Hi=∑i∈Ijhi ,则 (11) 可以简化为 (12)
L ( t ) = − 1 2 ∑ j = 1 T G j 2 H j + λ + Υ T L^{(t)}=-\frac{1}{2}\sum_{j=1}^{T}{\frac{G_{j}^{2}}{H_{j}+\lambda}}+\Upsilon T L(t)=−21∑j=1THj+λGj2+ΥT (12)
现在 (12) 可以做为得分值来评价一颗树的好坏,作为一个标准来进行剪枝操作(防止过拟合)。和决策树中的剪枝是一样的,给定一个损失函数,判断剪枝后,根据损失函数是否减小来决定是否执行剪枝,只是XGBoost是运用 (12) 来作为损失函数判断的标准。
3、生成树
上面的公式都是基于给定一个树的前提下推导而来的,那么这颗树是怎么生成的呢?
在决策树的生成中,我们用ID3、C4.5、Gini指数等指标去选择最优分裂特征、切分点(CART时),XGBoost同样定义了特征选择和切分点选择的指标:
G a i n = 1 2 [ G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ ] − γ Gain=\frac{1}{2}[\frac{G_{L}^{2}}{H_{L}+\lambda}+\frac{G_{R}^{2}}{H_{R}+\lambda}-\frac{(G_{L}+G_{R})^2}{H_{L}+H_{R}+\lambda}]-\gamma Gain=21[HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2]−γ (13)
XGBoost中使用过 (13) 判断切分增益,Gain值越大,说明分裂后能使目标函数减少越多,就越好。其中 G L 2 H L + λ \frac{G_{L}^{2}}{H_{L}+\lambda} HL+λGL2表示在某个节点按条件切分后左节点的得分, G R 2 H R + λ \frac{G_{R}^{2}}{H_{R}+\lambda} HR+λGR2表示在某个节点按条件切分后右节点的得分, ( G L + G R ) 2 H L + H R + λ \frac{(G_{L}+G_{R})^2}{H_{L}+H_{R}+\lambda} HL+HR+λ(GL+GR)2表示切分前的得分,γ表示切分后模型复杂度的增加量。现在有了判断增益的方法,就需要使用该方法去查找最优特征以及最优切分点。
六、分裂查找算法
关于最优特征以及最优切分点的选取XGBoost提供了两个算法。
- Basic Exact Greedy Algorithm (精确贪心算法)
- Approximate Algorithm(近似算法)
精确贪心算法类似于CART中最优特征与切分点的查找,通过遍历每个特征下的每个可能的切分点取值,计算切分后的增益,选择增益最大的特征及切分点。因为精确贪心算法需要遍历所有特征和取值,当数据量非常大的时候,无法将所有数据同时加载进内存时,精确贪心算法会非常耗时。
所以,XGBoost的作者引进了近似算法。近似算法对特征值进行了近似处理,即根据每个特征k的特征值分布,确定出候选切分点
S
k
=
{
s
k
1
,
s
k
2
,
.
.
.
,
s
k
l
}
S_{k}=\left\{ s_{k1}, s_{k2},...,s_{kl}\right\}
Sk={sk1,sk2,...,skl},即按特征分布将连续的特征值划分到
l
l
l 个候选点对应的桶(buckets)中,并且对每个桶中每个样本的
G
i
、
H
i
G_{i}、H_{i}
Gi、Hi 进行累加。
划分好候选切分点之后,按照精确贪心算法描述的算法步骤进行选择最优切分特征与最优切分点,不同的是切分点被上述候选切分点所代替,但原理和操作过程是一样的。
文章参考:参考文章来源