第一篇博客,就记录一下最近学习的XGBoost算法吧。主要参考了下面这篇文章
xgboost的原理没你想像的那么难
1. XGBoost模型
和GBDT一样,XGBoost也是集成学习的一种方法,并且弱学习器采用的也是CART回归树。下面是模型的数学表述:
设训练样本集为
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
…
,
(
x
m
,
y
m
)
}
\{(x_1,y_1),(x_2,y_2),\ldots,(x_m,y_m)\}
{(x1,y1),(x2,y2),…,(xm,ym)},第
k
k
k棵CART树是
f
k
(
x
)
f_k(x)
fk(x),整个模型一共由
K
K
K棵树组成。对于某一个样本
x
i
x_i
xi,模型给出的预测输出为:
y
i
^
=
∑
k
=
1
K
f
k
(
x
i
)
\hat{y_i}=\sum\limits_{k=1}^Kf_k(x_i)
yi^=k=1∑Kfk(xi)
为了找到最优的XGBoost模型,就是要最小化下面的目标函数:
o
b
j
(
θ
)
=
∑
i
=
1
m
L
(
y
i
,
y
i
^
)
+
∑
k
=
1
K
Ω
(
f
k
)
(
∗
)
obj(\theta)=\sum\limits_{i=1}^mL(y_i,\hat{y_i})+\sum_{k=1}^K\Omega(f_k)\qquad\qquad(*)
obj(θ)=i=1∑mL(yi,yi^)+k=1∑KΩ(fk)(∗)
其中,
L
L
L是损失函数,
Ω
(
f
)
\Omega(f)
Ω(f)表示CART树的复杂度,是正则化项。
2. XGBoost基本原理
2.1 加法模型
和GBDT一样,XGBoost也是采用加法模型的迭代方法进行训练。具体地,我们的目标不再是一次性优化整个目标函数
(
∗
)
(*)
(∗),转而变成分步优化。
假设已经经过了
t
−
1
t-1
t−1轮的迭代,得到了
t
−
1
t-1
t−1棵CART树,则当前第
t
t
t轮的目标是找到一颗树
f
t
(
x
)
f_t(x)
ft(x),使得现有模型加上这棵树后,目标损失最小化:
m
i
n
  
o
b
j
(
t
)
=
∑
i
=
1
m
L
(
y
i
,
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
)
+
∑
k
=
1
t
Ω
(
f
k
)
=
∑
i
=
1
m
L
(
y
i
,
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
)
+
Ω
(
f
t
)
+
C
o
n
s
t
a
n
t
min\;obj^{(t)}=\sum_{i=1}^mL\big(y_i,\hat{y_i}^{(t-1)}+f_t(x_i)\big)+\sum_{k=1}^t\Omega(f_k)\\ =\sum_{i=1}^mL\big(y_i,\hat{y_i}^{(t-1)}+f_t(x_i)\big)+\Omega(f_t)+Constant
minobj(t)=i=1∑mL(yi,yi^(t−1)+ft(xi))+k=1∑tΩ(fk)=i=1∑mL(yi,yi^(t−1)+ft(xi))+Ω(ft)+Constant
上面式子中,
y
i
^
(
t
−
1
)
\hat{y_i}^{(t-1)}
yi^(t−1)是现有的
t
−
1
t-1
t−1棵树加起来对样本
x
i
x_i
xi的预测输出,
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
\hat{y_i}^{(t-1)}+f_t(x_i)
yi^(t−1)+ft(xi)就是当前第
t
t
t轮结束之后模型的预测输出。
2.2 Taylor展开
对于一般的损失函数
L
(
y
,
y
^
)
L(y,\hat{y})
L(y,y^),我们可以做二阶泰勒展开如下:
L
(
y
,
y
^
+
δ
)
≈
L
(
y
,
y
^
)
+
∂
y
^
L
(
y
,
y
^
)
⋅
δ
+
1
2
∂
y
^
2
L
(
y
,
y
^
)
⋅
δ
2
L(y,\hat{y}+\delta)\approx L(y,\hat{y})+\partial_{\hat{y}}L(y,\hat{y})\cdot\delta+\frac{1}{2}\partial{\hat{y}}^2L(y,\hat{y})\cdot\delta^2
L(y,y^+δ)≈L(y,y^)+∂y^L(y,y^)⋅δ+21∂y^2L(y,y^)⋅δ2
代入到上面的目标函数中,我们有下面的形式:
m
i
n
  
o
b
j
(
t
)
≈
∑
i
=
1
m
[
L
(
y
i
,
y
i
^
(
t
−
1
)
)
+
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
(
x
i
)
2
]
+
Ω
(
f
t
)
+
C
o
n
s
t
a
n
t
min\;obj^{(t)}\approx\sum_{i=1}^m\big[L(y_i,\hat{y_i}^{(t-1)})+g_if_t(x_i)+\frac{1}{2}h_if_t(x_i)^2\big]+\Omega(f_t)+Constant
minobj(t)≈i=1∑m[L(yi,yi^(t−1))+gift(xi)+21hift(xi)2]+Ω(ft)+Constant
其中:
g
i
=
∂
∂
y
^
L
(
y
i
,
y
i
^
(
t
−
1
)
)
h
i
=
∂
2
∂
y
^
2
L
(
y
i
,
y
i
^
(
t
−
1
)
)
g_i=\frac{\partial}{\partial\hat{y}}L(y_i,\hat{y_i}^{(t-1)}) \\ h_i=\frac{\partial^2}{\partial{\hat{y}^2}}L(y_i,\hat{y_i}^{(t-1)})
gi=∂y^∂L(yi,yi^(t−1))hi=∂y^2∂2L(yi,yi^(t−1))
现在重新观察上面的目标函数,其中
L
(
y
i
,
y
i
^
(
t
−
1
)
)
L(y_i,\hat{y_i}^{(t-1)})
L(yi,yi^(t−1))是常数,
g
i
,
h
i
,
C
o
n
s
t
a
n
t
g_i,h_i,Constant
gi,hi,Constant也是常数,变量只有
f
t
(
x
i
)
f_t(x_i)
ft(xi)和
Ω
(
f
t
)
\Omega(f_t)
Ω(ft)。因此,第
t
t
t轮训练的优化目标等价于最小化下式:
m
i
n
  
∑
i
=
1
m
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
(
x
i
)
2
]
+
Ω
(
f
t
)
(
⋆
)
min\;\sum_{i=1}^m\big[g_if_t(x_i)+\frac{1}{2}h_if_t(x_i)^2\big]+\Omega(f_t)\qquad(\star)
mini=1∑m[gift(xi)+21hift(xi)2]+Ω(ft)(⋆)
2.3 模型正则化——CART树的复杂度
上面的优化目标中,涉及到正则化项,下面介绍XGBoost里对CART树复杂度的定义。
首先用数学语言描述一棵CART树::
f
(
x
)
=
w
q
(
x
)
,
    
w
∈
R
T
,
    
q
:
R
T
→
{
1
,
2
,
…
,
T
}
f(x)=w_{q(x)},\;\;w\in\mathcal{R}^T,\;\;q:\mathcal{R}^T\rightarrow\{1,2,\ldots,T\}
f(x)=wq(x),w∈RT,q:RT→{1,2,…,T}
这棵树一共有
T
T
T个叶子节点,其取值组成一个向量
w
w
w。
q
(
x
)
q(x)
q(x)把样本
x
x
x映射到某一个叶子节点对应的编号,表示这棵树把
x
x
x分到了那个叶子节点。
q
(
x
)
q(x)
q(x)体现了树的结构。
根据上面的定义,XGBoost定义一棵树的复杂度如下:
Ω
(
f
)
=
γ
T
+
1
2
λ
∑
j
=
1
T
w
j
2
\Omega(f)=\gamma T+\frac{1}{2}\lambda\sum_{j=1}^Tw_j^2
Ω(f)=γT+21λj=1∑Twj2
其中,参数
γ
,
  
λ
\gamma,\;\lambda
γ,λ需调参。
γ
\gamma
γ越大,对树的叶子个数惩罚越大,代表了我们希望获得结构更简单的树;
λ
\lambda
λ同理。
2.4 最终简化
现在把树的复杂度定义代入,得到第
t
t
t轮训练的优化目标为:
m
i
n
  
∑
i
=
1
m
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
(
x
i
)
2
]
+
γ
T
+
1
2
λ
∑
j
=
1
T
w
j
2
f
t
(
x
)
=
w
q
(
x
)
min\;\sum_{i=1}^m\big[g_if_t(x_i)+\frac{1}{2}h_if_t(x_i)^2\big]+\gamma T+\frac{1}{2}\lambda\sum_{j=1}^Tw_j^2 \\ f_t(x)=w_{q(x)}
mini=1∑m[gift(xi)+21hift(xi)2]+γT+21λj=1∑Twj2ft(x)=wq(x)
如果我们把上面的求和展开成一项一项的:
g 1 w q ( x 1 ) + … + g m w q ( x m ) + 1 2 h 1 w q ( x 1 ) 2 + … + 1 2 h m w q ( x m ) 2 + 1 2 λ w 1 2 + … + 1 2 λ w T 2 + γ T g_1 w_{q(x_1)}+ \ldots+g_m w_{q(x_m)} + \frac{1}{2}h_1 w_{q(x_1)}^2+\ldots+\frac{1}{2}h_mw_{q(x_m)}^2 +\frac{1}{2}\lambda w_1^2+\ldots+\frac{1}{2}\lambda w_T^2 +\gamma T g1wq(x1)+…+gmwq(xm)+21h1wq(x1)2+…+21hmwq(xm)2+21λw12+…+21λwT2+γT
然后按照
w
w
w的下标对应求和,就改写成下面的形式:
m
i
n
  
∑
j
=
1
T
[
G
j
w
j
+
1
2
(
H
j
+
λ
)
w
j
2
]
+
γ
T
(
⋆
⋆
)
min\;\sum_{j=1}^T\big[G_jw_j+\frac{1}{2}(H_j+\lambda)w_j^2\big]+\gamma T\qquad(\star\star)
minj=1∑T[Gjwj+21(Hj+λ)wj2]+γT(⋆⋆)
其中:
G
j
=
∑
i
∈
I
j
g
i
:
所
有
被
划
入
第
j
个
叶
子
节
点
的
样
本
对
应
的
g
i
之
和
H
j
=
∑
i
∈
I
j
h
i
:
所
有
被
划
入
第
j
个
叶
子
节
点
的
样
本
对
应
的
h
i
之
和
G_j=\sum\limits_{i\in I_j}g_i:所有被划入第j个叶子节点的样本对应的g_i之和\\ H_j=\sum\limits_{i\in I_j}h_i:所有被划入第j个叶子节点的样本对应的h_i之和
Gj=i∈Ij∑gi:所有被划入第j个叶子节点的样本对应的gi之和Hj=i∈Ij∑hi:所有被划入第j个叶子节点的样本对应的hi之和
对于我们要求的第
t
t
t棵CART树
f
t
(
x
)
f_t(x)
ft(x)来说,**假如叶子节点个数
T
T
T以及树的结构
q
(
x
)
q(x)
q(x)已知确定,则所有的
G
j
,
H
j
G_j,H_j
Gj,Hj都可以算出,并且每个叶子的得分值
w
j
w_j
wj彼此之间互相独立。**这样,要最小化
(
⋆
⋆
)
(\star\star)
(⋆⋆)式,就等价于对每一个求和的部分:
G
j
w
j
+
1
2
(
H
j
+
λ
)
w
j
2
,
  
j
=
1
,
2
,
…
,
T
G_jw_j+\frac{1}{2}(H_j+\lambda)w_j^2,\;j=1,2,\ldots,T
Gjwj+21(Hj+λ)wj2,j=1,2,…,T进行最小化。这是一个关于
w
j
w_j
wj的二次函数,最优解为:
w
j
∗
=
−
G
j
H
j
+
λ
(
⋆
⋆
⋆
)
o
b
j
∗
=
−
1
2
∑
j
=
1
T
G
j
2
H
j
+
λ
+
γ
T
w^*_j=-\frac{G_j}{H_j+\lambda}\quad\qquad(\star\star\star) \\ obj^*=-\frac{1}{2}\sum_{j=1}^T\frac{G_j^2}{H_j+\lambda}+\gamma T
wj∗=−Hj+λGj(⋆⋆⋆)obj∗=−21j=1∑THj+λGj2+γT
3. 寻找最优树
3.1 打分函数
我们要求第 t t t棵树,需要知道的是树的结构 q ( x ) q(x) q(x)以及每个叶子上的输出 w j w_j wj。对于任意一棵CART树,它的结构和输出本来应该是相互独立的,但是从上面的式子可以看出:使得目标损失最小化的 w j w_j wj取值完全依赖于 ( G j , H j ) (G_j,H_j) (Gj,Hj),而 { ( G j , H j ) } j = 1 T \{(G_j,H_j)\}_{j=1}^T {(Gj,Hj)}j=1T又完全决定了 o b j ∗ obj^* obj∗的大小。
o b j ∗ obj^* obj∗的大小表示了树的结构好坏程度,被称为打分函数。** o b j ∗ obj^* obj∗得分越小,树结构越好。**因此寻找最优树的过程就是:
- 找到使得 o b j ∗ obj^* obj∗最小的树结构 q ( x ) q(x) q(x),并根据这个 q ( x ) q(x) q(x)可以求出 G j , H j , j = 1 , 2 , … , T G_j,H_j,j=1,2,\ldots,T Gj,Hj,j=1,2,…,T
- 根据 ( ⋆ ⋆ ⋆ ) (\star\star\star) (⋆⋆⋆)式,求出对应的叶子得分 w j w_j wj。二者结合在一起就是我们要的树 f t ( x ) = w q ( x ) f_t(x)=w_{q(x)} ft(x)=wq(x)
可以这么理解:待优化的目标函数是关于 G , H , w G,H,w G,H,w的函数;固定 G , H G,H G,H不变时, w w w的改变会影响函数值。因此使得函数最小化的 w w w是一个关于 G , H G,H G,H的函数: w ∗ = w ( G , H ) w^*=w(G,H) w∗=w(G,H),然后再对 G , H G,H G,H遍历,找到使得函数达到最小的取值 G ∗ , H ∗ G^*,H^* G∗,H∗。
3.2 贪心策略
然而一棵决策树的结构有千千万万可能:不同的树深度,不同的划分特征,不同的划分特征取值等等。XGBoost采用贪心的方法来枚举不同的树结构。
用一个简单的例子来说明。训练样本是一个家庭里的五个成员,样本特征包括年龄、性别、职业等,问题是想判断每个人是否喜欢电子游戏。
现在假设这棵树是最普通的单节点树(所有样本属于同一个叶子),我们想按年龄这个特征对数据二分进两个叶子。这个时候就涉及决策树中的两个问题:
- 年龄特征是否是优选?
- 如果是,那按什么阈值划分?
XGBoost的策略如下:把所有样本按照年龄从小到大排序,如下图所示。切分点是图中的竖线,线左边的就是左子树
I
L
I_L
IL,右边的就是右子树
I
R
I_R
IR。把竖线从左向右扫描一遍,就可以得到按年龄划分的所有可能方法。
不妨考虑图上的这种划分标准,左叶子里有两个样本,右边叶子有三个样本。按照定义,有
G
L
=
g
1
+
g
4
G
R
=
g
2
+
g
3
+
g
5
T
=
2
G_L=g_1+g_4\\ G_R=g_2+g_3+g_5\\ T=2
GL=g1+g4GR=g2+g3+g5T=2
此时,我们的打分函数值等于:
o
b
j
∗
~
=
−
1
2
(
G
L
2
H
L
+
λ
+
G
R
2
H
R
+
λ
)
+
2
γ
\tilde{obj^*}=-\frac{1}{2}\big(\frac{G_L^2}{H_L+\lambda}+\frac{G_R^2}{H_R+\lambda}\big)+2\gamma
obj∗~=−21(HL+λGL2+HR+λGR2)+2γ
而没有添加年龄这个新划分点之前的得分等于:
o
b
j
∗
=
−
1
2
(
G
L
+
G
R
)
2
H
L
+
H
R
+
λ
+
γ
obj^*=-\frac{1}{2}\frac{(G_L+G_R)^2}{H_L+H_R+\lambda}+\gamma
obj∗=−21HL+HR+λ(GL+GR)2+γ
二者相减,定义:
g
a
i
n
=
o
b
j
∗
−
o
b
j
∗
~
=
1
2
(
G
L
2
H
L
+
λ
+
G
R
2
H
R
+
λ
−
(
G
L
+
G
R
)
2
H
L
+
H
R
+
λ
)
−
γ
(
∗
∗
)
gain = obj^*-\tilde{obj^*}=\frac{1}{2}\bigg(\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}\bigg)-\gamma\quad\quad(**)
gain=obj∗−obj∗~=21(HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2)−γ(∗∗)
之前我们说过, o b j ∗ obj^* obj∗的值是越小越好,所以如果 g a i n gain gain大于零,并且绝对值越大,说明这个划分越值得。从左到右扫描一遍,得到不同切分点并计算对应的 g a i n gain gain值,找到其中最大的那个,如果大于零,则决策树就按照这个标准衍生子树。
[注意]
观察 ( ∗ ∗ ) (**) (∗∗)式,左边的括号表示切分后 o b j ∗ obj^* obj∗的减少程度,如果这个值小于 γ \gamma γ,则 g a i n < 0 gain<0 gain<0,不应该切分。换句话说,** γ \gamma γ值越大,就要求切分后 o b j ∗ obj^* obj∗减少的越多,否则拒绝切分。**XGBoost在生成树的时候就已经考虑了树的复杂度问题,所以无需单独地剪枝。
4. XGBoost的优缺点
优点
- 在代价函数里引入正则项,降低了模型方差,使学习出的模型更简单,防止过拟合
- **XGBoost支持并行处理。**注意不是Tree粒度的并行,即使XGBoost也是在上一次迭代完后才能继续下一棵Tree的迭代的,这里的并行指的是特征粒度上。
- 支持自定义损失函数,只要二阶可微即可