文章目录
xgBoost推导
1. xgboost的目标函数
xgboost的目标函数定义为:损失函数 + 所有树的复杂度
O
b
j
=
∑
i
=
1
n
l
(
y
i
,
y
i
^
)
+
∑
k
=
1
K
Ω
(
f
k
)
(1)
Obj = \sum^n_{i=1}l(y_i, \hat{y_i}) + \sum^K_{k=1}Ω(f_k)\tag{1}
Obj=i=1∑nl(yi,yi^)+k=1∑KΩ(fk)(1)
n为样本集的样本数,
l
(
y
i
,
y
i
^
)
l(y_i, \hat{y_i})
l(yi,yi^) 是定义的损失函数,根据样本的标签和预测值得到损失值,K表示基模型(树)的数量,
Ω
(
f
k
)
Ω(f_k)
Ω(fk)表示第 k 颗树的复杂度,
f
k
f_k
fk表示第
k
k
k颗树
其中对于样本
i
i
i 的预测值为:将这个样本的特征矩阵
x
i
x_i
xi 带入整个模型的每一颗树里面的预测结果的加和
y
i
^
=
∑
k
=
1
K
f
(
x
i
)
(2)
\hat{y_i} = \sum^K_{k=1}f(x_i)\tag{2}
yi^=k=1∑Kf(xi)(2)
2. 第t颗树的学习
对于第 t 次迭代
y
i
^
(
t
)
=
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
(3)
\hat{y_i}^{(t)} = \hat{y_i}^{(t-1)} + f_t(x_i)\tag{3}
yi^(t)=yi^(t−1)+ft(xi)(3)
将 (3) 代入 (1) 得:
O
b
j
(
t
)
=
∑
i
=
1
n
l
(
y
i
,
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
)
+
∑
k
=
1
t
−
1
Ω
(
f
k
)
+
Ω
(
f
t
)
(4)
Obj^{(t)} = \sum^n_{i=1}l(y_i, \hat{y_i}^{(t-1)} + f_t(x_i)) + \sum^{t-1}_{k=1}Ω(f_k) + Ω(f_t)\tag{4}
Obj(t)=i=1∑nl(yi,yi^(t−1)+ft(xi))+k=1∑t−1Ω(fk)+Ω(ft)(4)
其中
y
i
^
(
t
−
1
)
\hat{y_i}^{(t-1)}
yi^(t−1) 和
∑
k
=
1
t
−
1
Ω
(
f
k
)
\sum^{t-1}_{k=1}Ω(f_k)
∑k=1t−1Ω(fk) 都是常量,只有一个变量,就是在第 t 次迭代的时候要求的
f
t
(
x
i
)
f_t(x_i)
ft(xi)
3. 对目标函数进行二阶泰勒展开
为了简化目标函数 O b j ( t ) Obj^{(t)} Obj(t) ,对其进行二阶泰勒展开:
二阶泰勒公式:
f
(
x
+
Δ
x
)
≈
f
(
x
)
+
f
′
(
x
)
Δ
x
+
1
2
f
′
′
(
x
)
Δ
x
f(x + \Delta{x}) \approx f(x) + f'(x)\Delta{x} + \frac{1}{2}f''(x)\Delta{x}
f(x+Δx)≈f(x)+f′(x)Δx+21f′′(x)Δx
其中,把
Δ
x
\Delta{x}
Δx 当作
f
t
(
x
i
)
f_t(x_i)
ft(xi) ,
x
x
x 当作
y
i
^
(
t
−
1
)
\hat{y_i}^{(t-1)}
yi^(t−1)
O b j ( t ) = ∑ i = 1 n [ l ( y i , y i ^ ( t − 1 ) + ∂ l ( y i , y i ^ ( t − 1 ) ) ∂ y i ^ ( t − 1 ) f t ( x i ) + 1 2 ∂ 2 l ( y i , y i ^ ( t − 1 ) ) ∂ y i ^ ( t − 1 ) 2 f t ( x i ) 2 ] + Ω ( f t ) + ∑ k = 1 t − 1 Ω ( f k ) (5) Obj^{(t)} = \sum^n_{i=1}[ l(y_i, \hat{y_i}^{(t-1)} + \frac{\partial l(y_i, \hat{y_i}^{(t-1)})}{\partial \hat{y_i}^{(t-1)}}f_t(x_i) + \frac{1}{2}\frac{\partial^{2}l(y_i, \hat{y_i}^{(t-1)})}{\partial \hat{y_i}^{(t-1)}{^{2}}} f_t(x_{i})^{2}] + Ω(f_t) +\sum^{t-1}_{k=1}Ω(f_k) \tag{5} Obj(t)=i=1∑n[l(yi,yi^(t−1)+∂yi^(t−1)∂l(yi,yi^(t−1))ft(xi)+21∂yi^(t−1)2∂2l(yi,yi^(t−1))ft(xi)2]+Ω(ft)+k=1∑t−1Ω(fk)(5)
令损失函数
l
l
l 关于
y
i
^
(
t
−
1
)
\hat{y_i}^{(t-1)}
yi^(t−1)的一阶偏导和二阶偏导分别为
g
i
g_i
gi 和
h
i
h_i
hi
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
)
2
(6)
g_i =\frac{\partial l(y_i, \hat{y_i}^{(t-1)})}{\partial \hat{y_i}^{(t-1)}}, h_i = \frac{\partial^{2}l(y_i, \hat{y_i}^{(t-1)})}{\partial \hat{y_i}^{(t-1)}{^{2}}} \tag{6}
gi=∂yi^(t−1)∂l(yi,yi^(t−1)),hi=∂yi^(t−1)2∂2l(yi,yi^(t−1))(6)
将 (6) 的 代入 (5) 并去掉里面的常数项,最后得到目标函数:
O
b
j
(
t
)
=
∑
i
=
1
n
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
(
x
i
)
2
)
]
+
Ω
(
f
t
)
(7)
Obj^{(t)} = \sum^n_{i=1}[g_if_t(x_i) + \frac{1}{2}h_if_t(x_i)^2) ] + Ω(f_t)\tag{7}
Obj(t)=i=1∑n[gift(xi)+21hift(xi)2)]+Ω(ft)(7)
4. 定义一颗树
一颗树由以下两方面决定:
- 叶子结点的权重向量 w j w_j wj
- 样本到叶子结点的映射(树的分支结构) q q q
一个样本对应的预测值,就是把样本放到分给模型里面的每一颗树,样本所落在的叶子结点的权重的和。
一颗树定义为
f
k
=
w
q
(
x
i
)
(8)
f_k = w_{q(x_i)} \tag{8}
fk=wq(xi)(8)
q
(
x
i
)
q(x_i)
q(xi) 表示,将一个样本
x
i
x_i
xi 代入这棵树,被分到的叶子结点的编号
5. 树的复杂度
树的复杂度由以下两方面组成:
- 叶子结点的数量 T
- 叶子结点的权重向量的正则项
此处为
L
2
L_2
L2 正则项
Ω
(
f
t
)
=
γ
T
+
1
2
λ
∑
j
=
1
T
w
j
2
(9)
Ω(f_t) = \gamma T + \frac{1}{2}\lambda \sum^T_{j=1}w^2_j \tag{9}
Ω(ft)=γT+21λj=1∑Twj2(9)
6. 对样本落入的叶子结点进行分组
将属于第 j 个叶子结点的所有样本 xi , 划入到一个叶子结点样本集中:
I
j
=
{
i
∣
q
(
x
i
)
=
j
}
I_j = \{i|q(x_i) = j\}
Ij={i∣q(xi)=j}
将 (8) (9) 代入 (7)
被分到同一个叶子结点里面的样本,对应的叶子结点的权重是相同的,这个样本集里面的所有样本的权重之和 = 所有被分到同一组的样本*该组的权重之和
令 G i = ∑ i ∈ I j g i G_i= \sum_{i\in I_j}g_i Gi=∑i∈Ijgi , H i = ∑ i ∈ I j h i H_i= \sum_{i\in I_j}h_i Hi=∑i∈Ijhi
-
G
j
G_j
Gj :叶子结点 j 所包含样本的
一阶偏导数
累加之和,是一个常量; -
H
j
H_j
Hj :叶子结点 j 所包含样本的
二阶偏导数
累加之和,是一个常量;
原式:
O
b
j
(
t
)
=
∑
j
=
1
T
[
G
j
w
j
+
1
2
(
H
j
+
λ
)
w
j
2
]
+
γ
T
(11)
Obj^{(t)} = \sum^T_{j=1} \Big[ G_jw_j + \frac{1}{2}(H_j + \lambda)w_j^2 \Big] + \gamma T \tag{11}
Obj(t)=j=1∑T[Gjwj+21(Hj+λ)wj2]+γT(11)
此时 F ( w j ) = G j w j + 1 2 ( H j + λ ) w j 2 F(w_j) = G_jw_j + \frac{1}{2}(H_j + \lambda)w_j^2 F(wj)=Gjwj+21(Hj+λ)wj2 就是一个自变量为 w j w_j wj 的二次函数
令
F
′
(
w
j
)
=
0
F'(w_j) = 0
F′(wj)=0 得:
w
j
∗
=
−
G
j
H
j
+
λ
F
(
w
j
∗
)
=
−
1
2
G
j
2
H
j
+
λ
(12)
w_j^* = -\frac{G_j}{H_j + \lambda}\\ F(w_j^*) = -\frac{1}{2}\frac{G_j^2}{H_j + \lambda} \tag{12}
wj∗=−Hj+λGjF(wj∗)=−21Hj+λGj2(12)
此时损失函数达到最小值,所以最优树结构对应的目标函数是:
O
b
j
(
t
)
=
−
1
2
∑
j
=
1
T
G
j
2
H
j
+
λ
+
γ
T
(13)
Obj^{(t)} = -\frac{1}{2}\sum^T_{j=1}\frac{G_j^2}{H_j + \lambda} + \gamma T \tag{13}
Obj(t)=−21j=1∑THj+λGj2+γT(13)
由于
γ
\gamma
γ 是认为给定的,所以此时树的目标值,就只和叶子结点的数量由关系了
7. 树结点的分裂
一个树结点可以看成是只有一颗只有根结点的树,所以一个树结点的分数为
S
c
o
r
e
=
−
1
2
G
j
2
H
j
+
λ
+
γ
Score = -\frac{1}{2} \frac{G_j^2}{H_j + \lambda} + \gamma
Score=−21Hj+λGj2+γ
xgboost规定,作为基模型的树是二叉树,所以一个结点,只能分为两个子结点,与决策树一样,我们要定义一个指标来衡量,按照某一个特征进行分支的前后的增益量
增益量定义:
G
a
i
n
=
O
b
j
L
+
R
−
(
O
b
j
L
+
O
b
j
R
)
=
1
2
[
G
L
2
H
L
+
λ
+
G
L
2
R
H
R
+
λ
−
(
G
L
+
G
R
)
2
H
L
+
H
R
λ
]
−
γ
\begin{aligned} Gain &= Obj_{L+R} - (Obj_L + Obj_R)\\ &= \frac{1}{2} \Big[ \frac{G^2_L}{H_L+\lambda} + \frac{G^2_LR}{H_R+\lambda} - \frac{(G_L + G_R)^2}{H_L+H_R\lambda} \Big] - \gamma \end{aligned}
Gain=ObjL+R−(ObjL+ObjR)=21[HL+λGL2+HR+λGL2R−HL+HRλ(GL+GR)2]−γ
当 Gain > 0 的时候,即分支后的损失相比于分支前下降了,才会考虑进行分支
8. 寻找最优分裂结点
寻找最佳分割点的大致步骤如下:
- 遍历每个结点的每个特征;
- 对每个特征,按特征值大小将特征值排序;
- 线性扫描,找出每个特征的最佳分裂特征值;
- 在所有特征中找出最好的分裂点(分裂后增益最大的特征及特征值)
为了更快的寻找最佳的分裂结点,xgboost采用了一些更好的方法:
- 特征预排序 + 缓存: xgboost在训练之前,预先对每一个特征的特征值进行预排序,保存为block结构,后面迭代的时候重复使用这个结构,减小计算量
- 分位点近似法:对每个特征按照特征值排序后,采用类似分位点选取的方式,仅仅选出常数个特征值作为该特征的候选分割点,在寻找该特征的最佳分割点时,从候选分割点中选出最优的一个。
- 并行查找:由于各个特性已预先存储为block结构,XGBoost支持利用多个线程并行地计算每个特征的最佳分割点,这不仅大大提升了结点的分裂速度,也极利于大规模训练集的适应性扩展。
9. 树的停止生长
- Gain < 0
- 树达到max_depth
- 如果一个结点的样本权重低于阈值, 此节点停止分裂