梯度提升树(Gradient Boosting Decison Tree, GBDT)是Boosting(提升)中的一种重要算法。
Adaboost算法利用前一轮迭代弱学习器的误差率来更新训练集的权重,训练得到新的基模型。在GBDT的迭代中,假设前一轮迭代得到的强学习器是 f t − 1 ( x ) f_{t-1}(x) ft−1(x), 损失函数是 L ( y , f t − 1 ( x ) ) L(y, f_{t-1}(x)) L(y,ft−1(x)), 本轮迭代的目标是找到一个CART回归树模型的弱学习器 h t ( x ) h_t(x) ht(x),让本轮的损失函数 L ( y , f t ( x ) ) = L ( y , f t − 1 ( x ) + h t ( x ) ) L(y, f_{t}(x)) =L(y, f_{t-1}(x)+ h_t(x)) L(y,ft(x))=L(y,ft−1(x)+ht(x))最小。也就是说,本轮迭代找到决策树,要让样本的损失尽量变得更小。GBDT通过迭代不断地拟合损失。
梯度提升树(GBDT)
从回归提升树算法(boosting tree)可以看出当损失函数是平方损失函数和指数函数时,每一步优化很简单。但对于一般的损失函数,则采用梯度提升(gradient boosting)算法。
其核心思想是:利用损失函数的负梯度在当前模型的值:
−
[
∂
L
(
y
,
f
(
x
i
)
)
∂
f
(
x
i
)
]
-\left[\frac{\partial L(y,f(x_i))}{\partial f(x_i)}\right]
−[∂f(xi)∂L(y,f(xi))]
作为回归问题提升树算法中的残差的近似值,拟合回归树。
为什么是负梯度拟合残差近似值?
我们的目标是找到一个
f
(
x
)
f(x)
f(x)使得损失函数
L
(
y
i
,
f
(
x
i
)
)
L(y_i, f(x_i))
L(yi,f(xi))的值最小,那么可以将
f
(
x
)
f(x)
f(x)视为参数,使用梯度下降法进行优化。假设当前找到的
f
(
x
)
=
f
m
−
1
(
x
)
f(x)=f_{m-1}(x)
f(x)=fm−1(x),则根据梯度下降算法,第m轮的
f
(
x
)
m
f(x)_m
f(x)m的迭代公式如下:
f
(
x
)
m
=
f
(
x
)
m
−
1
−
∂
L
(
y
i
,
f
m
−
1
(
x
i
)
)
∂
f
m
−
1
(
x
i
)
f(x)_m=f(x)_{m-1}-\frac{\partial L(y_i,\,f_{m-1}(x_i))}{\partial f_{m-1}(x_i)}
f(x)m=f(x)m−1−∂fm−1(xi)∂L(yi,fm−1(xi))
根据前向分步算法的加法模型有:
f
(
x
)
m
=
f
(
x
)
m
−
1
+
T
(
x
;
γ
)
f(x)_m=f(x)_{m-1}+T(x;\gamma)
f(x)m=f(x)m−1+T(x;γ)
其中
T
(
x
;
γ
)
=
β
b
(
x
i
;
γ
)
T(x;\gamma) =\beta b(x_i;\gamma)
T(x;γ)=βb(xi;γ),是新一轮需要训练的树模型。对比上面两个式子,不难得到:
T
(
x
;
γ
)
=
−
∂
L
(
y
i
,
f
m
−
1
(
x
i
)
)
∂
f
m
−
1
(
x
i
)
T(x;\gamma) =-\frac{\partial L(y_i,\,f_{m-1}(x_i))}{\partial f_{m-1}(x_i)}
T(x;γ)=−∂fm−1(xi)∂L(yi,fm−1(xi))
上面式子的左边为树的预测值,右边为真实值,所以整个过程就变成了每次拟合损失函数的负梯度的值:
r
m
i
=
−
[
∂
L
(
y
i
,
f
(
x
i
)
)
∂
f
(
x
i
)
]
f
(
x
)
=
f
m
−
1
(
x
)
r_{mi}=-[\frac{\partial L(y_i,\,f(x_i))}{\partial f(x_i)}]_{f(x)=f_{m-1}(x)}
rmi=−[∂f(xi)∂L(yi,f(xi))]f(x)=fm−1(x)
也就是说,通过拟合损失函数的负梯度值,就可以达到优化损失函数的目的。
上面的结论要求了损失函数必须一阶可导,因此损失函数的选择很重要。
回归梯度提升算法
输入: 训练数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x N , y N ) } , x i ∈ χ ⊆ R n , y i ∈ y ⊆ R T=\{(x_1,y_1),(x_2,y_2) ,\dots,(x_N,y_N)\},x_i \in \chi \sube \R^n ,y_i \in y \sube \R T={(x1,y1),(x2,y2),…,(xN,yN)},xi∈χ⊆Rn,yi∈y⊆R ;损失函数 L ( y , f ( x ) ) L(y,f(x)) L(y,f(x))
输出:回归树 f ^ ( x ) \hat{f}(x) f^(x)
步骤:
- 初始化
f 0 ( x ) = arg min c ∑ i = 1 N L ( y i , c ) f_0(x)=\arg\min\limits_c\sum_{i=1}^NL(y_i, c) f0(x)=argcmini=1∑NL(yi,c)
- 对 m = 1 , 2 , … , M m=1,2,\dots,M m=1,2,…,M
(a)对 i = 1 , 2 , … , N i=1,2,\dots,N i=1,2,…,N,计算
r m i = − [ ∂ L ( y i , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) r_{mi}=-\left[\frac{\partial L(y_i, f(x_i))}{\partial f(x_i)}\right]_{f(x)=f_{m-1}(x)} rmi=−[∂f(xi)∂L(yi,f(xi))]f(x)=fm−1(x)
(b)对 r m i r_{mi} rmi拟合一个回归树,得到第 m m m棵树的叶节点区域 R m j , j = 1 , 2 , … , J R_{mj}, j=1,2,\dots,J Rmj,j=1,2,…,J(c)对 j = 1 , 2 , … , J j=1,2,\dots,J j=1,2,…,J
c m j = arg min c ∑ x i ∈ R m j L ( y i , f m − 1 ( x i ) + c ) c_{mj}=\arg\min_c\sum_{xi\in R_{mj}}L(y_i,f_{m-1}(x_i)+c) cmj=argcminxi∈Rmj∑L(yi,fm−1(xi)+c)
(d)更新
f m ( x ) = f m − 1 ( x ) + ∑ j = 1 J c m j I ( x ∈ R m j ) f_m(x)=f_{m-1}(x)+\sum_{j=1}^Jc_{mj}I(x\in R_{mj}) fm(x)=fm−1(x)+j=1∑JcmjI(x∈Rmj)
- 得到回归树
f ^ ( x ) = f M ( x ) = ∑ m = 1 M ∑ j = 1 J c m j I ( x ∈ R m j ) \hat{f}(x)=f_M(x)=\sum_{m=1}^M\sum_{j=1}^Jc_{mj}I(x\in R_{mj}) f^(x)=fM(x)=m=1∑Mj=1∑JcmjI(x∈Rmj)
算法第1步初始化,估计使损失函数极小化的常数值,它是只有一个根结点的树。
第2(a)步计算损失函数的负梯度在当前模型的值,将它作为残差的估计。对于平方损失函数,它就是通常所说的残差:对于一般损失函数,它就是残差的近似值。
第2(b)步估计回归树叶结点区域,以拟合残差的近似值。
第2©步利用线性搜索估计叶结点区域的值,使损失函数极小化。
第2(d)步更新回归树。
第3步得到输出的最终模型f(x)
分类梯度提升算法
因为GBDT是通过拟合损失函数负梯度来进行学习的,GBDT分类算法与GBDT回归不同之处在于由于样本的输出值是不连续的,无法从输出类别去拟合输出的误差。通过选择合适的损失函数来解决这个问题。GBDT分类常用的损失函数如下:
-
指数损失
L ( y , f ( x ) ) = e ( − y f ( x ) ) L(y,f(x))=e^{(-yf(x))} L(y,f(x))=e(−yf(x)) -
对数似然损失(二分类)
L ( y , f ( x ) ) = l o g ( 1 + e ( − y f ( x ) ) ) L(y,f(x))=log\left(1+e^{(-yf(x))}\right) L(y,f(x))=log(1+e(−yf(x))) -
对数似然损失(多分类)
L ( y , f ( x ) ) = − ∑ k = 1 K y k l o g p k ( x ) L(y,f(x))=-\sum_{k=1}^Ky_k\,log\,p_k(x) L(y,f(x))=−k=1∑Kyklogpk(x)
当使用指数损失函数,此时GBDT退化为AdaBoost算法。所以通常使用对数似然损失函数来拟合损失。
二分类GBDT算法
-
输入:
- 训练数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } , x i ∈ X ⊆ R n , y i ∈ Y = { − 1 , + 1 } T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\},x_i\in X\subseteq R^n,y_i \in Y=\{-1,+1\} T={(x1,y1),(x2,y2),...,(xN,yN)},xi∈X⊆Rn,yi∈Y={−1,+1};损失函数 L ( y , f ( x ) ) = l o g ( 1 + e ( − y f ( x ) ) ) L(y,f(x))=log\left(1+e^{(-yf(x))}\right) L(y,f(x))=log(1+e(−yf(x)));最大迭代次数 M M M。
-
输出:
- 分类树 f ( x ) f(x) f(x)
-
初始化弱学习器 f 0 ( x ) = arg min c ∑ i = 1 N L ( y i , c ) f_0(x)=\mathop{\arg\min}_{c}\sum_{i=1}^{N}L(y_i,c) f0(x)=argminci=1∑NL(yi,c)
-
对 m = 1 , 2 , . . . , M m=1,2,...,M m=1,2,...,M
- 对
i
=
1
,
2
,
.
.
.
,
N
i=1,2,...,N
i=1,2,...,N,计算损失函数在当前模型的负梯度:
r m i = − [ ∂ L ( y i , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) = y i 1 + e ( y i f ( x i ) ) r_{mi}=-[\frac{\partial L(y_i,\,f(x_i))}{\partial f(x_i)}]_{f(x)=f_{m-1}(x)}=\frac{y_i}{1+e^{(y_i\,f(x_i))}} rmi=−[∂f(xi)∂L(yi,f(xi))]f(x)=fm−1(x)=1+e(yif(xi))yi
- 对
i
=
1
,
2
,
.
.
.
,
N
i=1,2,...,N
i=1,2,...,N,计算损失函数在当前模型的负梯度:
-
利用 ( x i , r m i ) ( i = 1 , 2 , . . . , N ) (x_i,r_{mi})\,(i=1,2,...,N) (xi,rmi)(i=1,2,...,N),拟合一棵CART树,得到第 m m m棵树,其对应的叶子节点区域为 R m j , j = 1 , 2 , . . . , J R_{mj},\,j=1,2,...,J Rmj,j=1,2,...,J。其中 J J J为树 m m m的叶子节点的个数。
-
对 j = 1 , 2 , . . . , J j=1,2,...,J j=1,2,...,J,在损失函数极小化条件下,估计出相应叶节点区域的最佳拟合值:
c m j = arg min c ∑ x j ∈ R m j N l o g ( 1 + e ( − y i ( f t − 1 ( x i ) + c ) ) ) c_{mj}=\mathop{\arg\min}_{c}\sum_{x_j\in R_{mj}}^{N}log\left(1+e^{(-y_i(f_{t-1}(x_i)+c))}\right) cmj=argmincxj∈Rmj∑Nlog(1+e(−yi(ft−1(xi)+c)))-
由于上式比较难优化,我们一般使用近似值代替:
c m j = ∑ x j ∈ R m j / ∑ x j ∈ R m j ∣ r m i ∣ ( 1 − ∣ r m i ∣ ) c_{mj}=\sum_{x_j\in R_{mj}}/\sum_{x_j\in R_{mj}}|r_{mi}|(1-|r_{mi}|) cmj=xj∈Rmj∑/xj∈Rmj∑∣rmi∣(1−∣rmi∣) -
更新强学习器:
f m ( x ) = f m − 1 ( x ) + ∑ j = 1 J c m j I ( x ∈ R m j ) f_m(x)=f_{m-1}(x)+\sum_{j=1}^{J}c_{mj}\,I(x\in R_{mj}) fm(x)=fm−1(x)+j=1∑JcmjI(x∈Rmj)
-
-
得到强学习器 f ( x ) f(x) f(x)的表达式:
f ( x ) = f M ( x ) = f 0 ( x ) + ∑ m = 1 M ∑ j = 1 J c m j I ( x ∈ R m j ) f(x)=f_M(x)=f_0(x)+\sum_{m=1}^M\sum_{j=1}^{J}c_{mj}\,I(x\in R_{mj}) f(x)=fM(x)=f0(x)+m=1∑Mj=1∑JcmjI(x∈Rmj)
不难发现,除了负梯度计算和叶子节点的最佳负梯度拟合的线性搜索,二元GBDT分类和GBDT回归算法过程相同。
多分类GBDT算法
考虑到分类和回归算法的过程相似性,以下就阐述多分类GBDT算法的时候不再给出具体的流程,而仅仅列出差异的部分。
多分类GBDT比二分类GBDT复杂些,对应的是多元逻辑回归和二元逻辑回归的复杂度差别。假设类别数为
K
K
K,则此时我们的对数似然损失函数为:
L
(
y
,
f
(
x
)
)
=
−
∑
k
=
1
K
y
k
l
o
g
p
k
(
x
)
L(y,f(x))=-\sum_{k=1}^Ky_k\,log\,p_k(x)
L(y,f(x))=−k=1∑Kyklogpk(x)
其中如果样本输出类别为
k
k
k,则
y
i
y_i
yi =1,第
k
k
k 类的概率
p
k
(
x
)
p_k(x)
pk(x) 的表达式为:
p
k
(
x
)
=
e
f
k
(
x
)
∑
l
=
1
K
e
f
l
(
x
)
p_k(x)=\frac{e^{f_k(x)}}{\sum_{l=1}^{K}e^{f_l(x)}}
pk(x)=∑l=1Kefl(x)efk(x)
集合上两式,我们可以计算出第
m
m
m 轮的第
i
i
i 个样本对应类别
l
l
l 的负梯度误差为:
r
m
i
l
=
−
[
∂
L
(
y
i
,
f
(
x
i
)
)
∂
f
(
x
i
)
]
f
(
x
)
=
f
l
,
m
−
1
(
x
)
=
y
i
l
−
p
l
,
m
−
1
(
x
i
)
r_{mil}=-[\frac{\partial L(y_i,\,f(x_i))}{\partial f(x_i)}]_{f(x)=f_{l,\,m-1}(x)}=y_{il}-p_{l,m-1}(x_i)
rmil=−[∂f(xi)∂L(yi,f(xi))]f(x)=fl,m−1(x)=yil−pl,m−1(xi)
观察上式可以看出,其实这里的误差就是样本 i i i 对应类别 l l l 的真实概率和 t − 1 t-1 t−1 轮预测概率的差值。
对于生成的决策树,我们各个叶子节点的最佳负梯度拟合值为:
c
m
j
l
=
arg
min
c
j
l
∑
i
=
0
m
∑
k
=
1
K
L
(
y
k
,
f
m
−
1
,
l
(
x
)
+
∑
j
=
0
J
c
j
l
I
(
x
i
∈
R
m
j
)
)
c_{mjl}=\mathop{\arg\min}_{c_{jl}}\sum_{i=0}^{m}\sum_{k=1}^{K}L\left(y_k,\,f_{m-1,\,l}(x)+\sum_{j=0}^{J}c_{jl}\,I(x_i \in R_{mj})\right)
cmjl=argmincjli=0∑mk=1∑KL(yk,fm−1,l(x)+j=0∑JcjlI(xi∈Rmj))
由于上式比较难优化,我们一般使用近似值代替:
c
m
j
l
=
K
K
−
1
∑
x
i
∈
R
m
j
l
r
m
i
l
∑
x
i
∈
R
m
i
l
∣
r
m
i
l
∣
(
1
−
∣
r
m
i
l
∣
)
c_{mjl}=\frac{K}{K-1}\frac{\sum_{x_i\in R_{mjl}}r_{mil}}{\sum_{x_i\in R_{mil}}|r_{mil}|(1-|r_{mil}|)}
cmjl=K−1K∑xi∈Rmil∣rmil∣(1−∣rmil∣)∑xi∈Rmjlrmil
除了负梯度计算和叶子节点的最佳负梯度拟合的线性搜索,多分类GBDT与二分类GBDT以及GBDT回归算法过程相同。
GBDT正则化
GBDT有非常快降低Loss的能力,这也会造成一个问题:Loss迅速下降,模型偏差(bias),方差(variance)高,造成过拟合。下面简单介绍GBDT中抵抗过拟合的方法:
- 限制树的复杂度,即对弱学习器CART树进行正则化剪枝,比如如控制树的最大深度、节点的最少样本数、最大叶子节点数、节点分支的最小样本数等
- Shrinkage,其思想认为,每次走一小步逐渐逼近结果的效果,要比每次迈一大步很快逼近结果的方式更容易避免过拟合。即它不完全信任每一个棵残差树,它认为每棵树只学到了真理的一小部分,累加的时候只累加一小部分,通过多学几棵树弥补不足。用方程来看更清晰,即给每棵数的输出结果乘上一个步长 α \alpha α(learning rate)
对于前面的弱学习器的迭代:
f m ( x ) = f m − 1 ( x ) + T ( x ; γ m ) f_m(x)=f_{m-1}(x)+T(x;\gamma_m) fm(x)=fm−1(x)+T(x;γm)
加上正则化项,则有
f m ( x ) = f m − 1 ( x ) + α T ( x ; γ m ) f_m(x)=f_{m-1}(x)+\alpha\, T(x;\gamma_m) fm(x)=fm−1(x)+αT(x;γm)
此处, α \alpha α的取值范围为(0,1]。对于同样的训练集学习效果,较小 α \alpha α的意味着需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起决定算法的拟合效果。
优缺点
优点
- 可以灵活处理各种类型的数据,包括连续值和离散值
- 具有伸缩不变性,不用归一化特征
- 具有特征组合和特征选择的作用
- 可自然地处理缺失值
- 相对SVM而言,在相对较少的调参时间情况下,预测的准确率也比较高
- 在使用一些健壮的损失函数,对异常值得鲁棒性非常强。比如Huber损失函数和Quantile损失函数
缺点
- 由于弱学习器之间存在较强依赖关系,难以整体并行训练
参考链接:GBDT算法梳理