本节主要讲
1.什么是xgboost
2.xgboost的思想
3.xgboost算法中的一些细节
-
划分点打分函数推导
-
xgb中避免过拟合的方法总结
-
最优分裂点选择
-
缺失值处理
-
并行计算设计
1.什么是xgboost
xgboost是xetreme gradient boost(极度梯度提升的缩写),是梯度提升树(GBDT)的一种实现方式,更加高效并且效果更好。
2.xgboost的思想
跟GBDT一样,xgb模型也是加法模型,也是通过不断的新增一棵树来降低偏差。加法模型的表示:
y
i
^
=
ϕ
(
x
i
)
=
∑
k
=
i
K
f
(
x
i
)
\hat{y_i}=\phi(x_i)=\sum_{k=i}^Kf(x_i)
yi^=ϕ(xi)=k=i∑Kf(xi)
其中,每个f(x)都表示一颗CART树。CART树可以分为两个部分,叶子节点和非叶子节点。叶子节点表示划分的类别,每个叶子节点j模型都给出一个预测值
w
j
w_j
wj。非叶子节点代表划分规则
q
(
x
)
q(x)
q(x)。CART树的函数表示为:
f
(
x
)
=
∑
j
=
1
T
w
j
I
j
(
i
∣
q
(
x
)
=
j
)
f(x)=\sum_{j=1}^Tw_jI_j(i|q(x)=j)
f(x)=j=1∑TwjIj(i∣q(x)=j)
一棵树的判别过程就是根据划分规则q(x)将样本
x
i
x_i
xi划分到叶节点
I
j
I_j
Ij,并将当前叶节点的权重
w
j
w_j
wj作为该样本的预测值。
定义loss函数:
L
t
o
t
a
l
=
∑
i
=
1
m
l
(
y
i
,
y
i
^
)
+
∑
k
=
1
K
Ω
(
f
k
)
L_{total}=\sum_{i=1}^ml(y_i,\hat{y_i})+\sum_{k=1}^K\Omega(f_k)
Ltotal=i=1∑ml(yi,yi^)+k=1∑KΩ(fk)
其中
l
(
y
i
,
y
i
^
)
l(y_i,\hat{y_i})
l(yi,yi^)表示每一个样本的误差;
Ω
(
f
k
)
\Omega(f_k)
Ω(fk)表示第k棵树的正则项,论文给出正则项包括以下两部分(树叶节点的个数以及叶节点权重的二范数)。
Ω
(
f
k
)
=
γ
T
+
1
2
λ
∑
j
=
1
T
w
j
2
\Omega(f_k)=\gamma T+\frac{1}{2}\lambda\sum_{j=1}^Tw_j^2
Ω(fk)=γT+21λj=1∑Twj2
在第t论迭代时,我们的优化目标时,贪婪的增加一棵树
f
k
f_k
fk最小化损失函数。此时前t-1棵树已知。当前的loss可表示为:
L
t
o
t
a
l
=
∑
i
=
1
m
l
(
y
i
,
y
i
t
−
1
+
f
t
(
x
i
)
)
+
∑
k
=
1
t
−
1
Ω
(
f
k
)
+
Ω
(
f
t
)
L_{total}=\sum_{i=1}^ml(y_i,y_i^{t-1}+f_t(x_i))+\sum_{k=1}^{t-1}\Omega(f_k)+\Omega(f_t)
Ltotal=i=1∑ml(yi,yit−1+ft(xi))+k=1∑t−1Ω(fk)+Ω(ft)
使用泰勒二阶展开近似:
L
t
≃
∑
i
=
1
m
[
l
(
y
i
,
y
i
t
−
1
)
+
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
∑
k
=
1
t
−
1
Ω
(
f
k
)
+
Ω
(
f
t
)
L^t\simeq\sum_{i=1}^m[l(y_i,y_i^{t-1})+g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)]+\sum_{k=1}^{t-1}\Omega(f_k)+\Omega(f_t)
Lt≃i=1∑m[l(yi,yit−1)+gift(xi)+21hift2(xi)]+k=1∑t−1Ω(fk)+Ω(ft)
在t轮迭代时,前t-i棵树是已知的,所以上式中
l
(
y
i
,
y
i
t
−
1
)
,
∑
k
=
1
t
−
1
Ω
(
f
k
)
l(y_i,y_i^{t-1}),\sum_{k=1}^{t-1}\Omega(f_k)
l(yi,yit−1),∑k=1t−1Ω(fk)这两项是常数。优化目标等价于优化下面目标:
L
t
^
=
∑
i
=
1
m
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
Ω
(
f
t
)
\hat{L^t}=\sum_{i=1}^m[g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)]+\Omega(f_t)
Lt^=i=1∑m[gift(xi)+21hift2(xi)]+Ω(ft)
并且,对样本集的求和等价于先对叶节点求和,在对每个叶节点的所有样本求和,因为每个样本必定属于一个叶节点,且只能属于一个叶节点。即:
L
t
^
=
∑
j
=
1
T
[
∑
x
i
∈
I
j
g
i
w
j
+
1
2
∑
x
i
∈
I
j
h
i
w
j
2
]
+
γ
T
+
1
2
λ
∑
j
=
1
T
w
j
2
\hat{L^t}=\sum_{j=1}^T[\sum_{x_i\in I_j}g_iw_j+\frac{1}{2}\sum_{x_i\in I_j}h_iw_j^2]+\gamma T+\frac{1}{2}\lambda\sum_{j=1}^Tw_j^2\\
Lt^=j=1∑T[xi∈Ij∑giwj+21xi∈Ij∑hiwj2]+γT+21λj=1∑Twj2
= ∑ j = 1 T [ ∑ x i ∈ I j g i w j + 1 2 ( ∑ x i ∈ I j h i + λ ) w j 2 ] + γ T (1) =\sum_{j=1}^T[\sum_{x_i\in I_j}g_iw_j+\frac{1}{2}(\sum_{x_i\in I_j}h_i+\lambda)w_j^2]+\gamma T\tag{1} =j=1∑T[xi∈Ij∑giwj+21(xi∈Ij∑hi+λ)wj2]+γT(1)
将公式(1)看做关于w的一元二次函数,根据一元二次方程的最值公式:
x
∗
=
−
b
2
a
,
y
∗
=
4
a
c
−
b
2
4
a
x^*=-\frac{b}{2a},y^*=\frac{4ac-b^2}{4a}
x∗=−2ab,y∗=4a4ac−b2
可得,在树结构确定的情况下,最优解w和最优值y分别为:
w
∗
=
−
∑
x
i
∈
I
j
g
i
∑
x
i
∈
I
j
h
i
+
λ
,
L
∗
=
γ
T
−
∑
j
=
1
T
(
∑
x
i
∈
I
j
g
i
)
2
2
(
∑
x
i
∈
I
j
h
i
+
λ
)
w^*=-\frac{\sum_{x_i\in I_j}g_i}{\sum_{x_i\in I_j}h_i+\lambda},L^*=\gamma T-\sum_{j=1}^T\frac{(\sum_{x_i\in I_j}g_i)^2}{2(\sum_{x_i\in I_j}h_i+\lambda)}
w∗=−∑xi∈Ijhi+λ∑xi∈Ijgi,L∗=γT−j=1∑T2(∑xi∈Ijhi+λ)(∑xi∈Ijgi)2
函数(1)就是根据泰勒二阶展开得到损失函数的等价函数。直观上,我们可以列举每一颗可能的树结构,然后分别计算loss,选择loss最小的模型作为优化后的模型。但是穷举所有可能的树是做不到的。为此,采用贪婪算法,从根节点开始,每次贪婪的对节点进行分类。最终生长成为一棵树(决策树的生成是NP问题,使用启发式的算法求解)。
目的:
每次增加一棵树,使得loss函数最小化。
xgb做法:
3.xgb细节
3.1 分裂点的选择
简单说,就是选择使得loss下降幅度最大的候选点作为分裂点。
假设某一叶节点j,属于该节点样本的一阶导数和,二阶导数和分别为
G
=
∑
x
i
∈
I
j
g
i
,
H
=
∑
x
i
∈
I
j
h
i
G=\sum_{x_i\in I_j}g_i,H=\sum_{x_i\in I_j}h_i
G=∑xi∈Ijgi,H=∑xi∈Ijhi那么以此节点为决策树的最优loss值为:
m
i
n
L
=
−
1
2
G
2
H
+
λ
+
γ
\mathop{min}{L}=-\frac{1}{2}\frac{G^2}{H+\lambda}+\gamma
minL=−21H+λG2+γ
假设按照某一候选点划分为左右两个子节点后,划分后的最优loss为:
−
1
2
G
L
2
H
L
+
λ
−
1
2
G
R
2
H
R
+
λ
+
2
γ
-\frac{1}{2}\frac{G_L^2}{H_L+\lambda}-\frac{1}{2}\frac{G_R^2}{H_R+\lambda}+2\gamma
−21HL+λGL2−21HR+λGR2+2γ
则按照此方式分裂后loss下降的幅度为:
s
c
o
r
e
=
1
2
(
G
L
2
H
L
+
λ
+
G
R
2
H
R
+
λ
−
G
2
H
+
λ
)
−
γ
score=\frac{1}{2}(\frac{G_L^2}{H_L+\lambda}+\frac{G_R^2}{H_R+\lambda}-\frac{G^2}{H+\lambda})-\gamma
score=21(HL+λGL2+HR+λGR2−H+λG2)−γ
我们将loss下降的幅度作为候选分裂点的得分来选择当前最优的分裂点。上式即为打分函数。
3.2xgb的防止过拟合方法
(1)loss函数中的正则项
Ω ( f k ) = γ T + 1 2 λ ∑ j = 1 T w j 2 \Omega(f_k)=\gamma T+\frac{1}{2}\lambda\sum_{j=1}^Tw_j^2 Ω(fk)=γT+21λj=1∑Twj2
(2)shrinkage(收缩)
对每个树的每一个叶子乘以一个缩减权重n,减小每一颗树的影响力,为后面的树留更多的学习空间。
1.为了得到更多的树
2.类似于学习率,更小的学习率可以避免优化过程中loss来回震荡,loss会更平稳的收敛。
(3)列采样
集成学习中,为增加基学习期的多样性,一般有以下方法(参考周志华老师的西瓜书):
1.数据样本扰动(行采样)
2.特征扰动(列采样)
3.输出表示扰动
4.模型参数扰动
一般将数据样本表示为二维数据,行表示样本数,列表示特征数。所以数据样本扰动称为行采样,特征扰动称为列采样。
3.3分裂查找算法
(1)精确的贪婪算法
遍历每个特征,每个可能的候选点,分别计算score,得分最大最为分裂点。
(2)近似算法
按特征值的分布,设置百分比候选分裂点,然后将特征分通。这样减少了需要搜索的范围。一般按照设置候选分裂点的时间可分为全局近似算法与局部近似算法。
- 全局近似算法:在构造树前,预设所有的候选分裂点。每次分裂从中选择
- 局部近似算法:每次分裂后,重新预设候选分裂点。
两种方式的效果接近,只是全部近似需要的候选分裂点多。
3.4缺失值处理
xgb可自动学习特征缺失值的默认划分方向。
若训练样本的某一维特征存在缺失值,那么在计算该特征的候选分裂点得分时,先不考虑缺失样本,使用未缺失样本进行计算。在每一个候选分裂点得分计算时,分别计算将缺失样本划分到左右子节点的得分。选择得分最高的划分方式作为缺失值的默认划分方向。
3.5并行计算设计
xgb属于boosting,在每棵树的构建是串行的。只是在当前树构建时,选择最优划分点时进行了并行化处理。xgb算法的耗时主要在于选择最优分类点时,对节点按特征值进行排序。xgb在构建前,将数据存入block中,每列按照特征值排好序。避免了每次都进行排序的操作。多个特征的候选分裂点得分计算并行。
参考:
[1]陈天奇的论文 XGBoost: A Scalable Tree Boosting Systerm
[2]知乎详解:https://zhuanlan.zhihu.com/p/92837676