Gradient Boosting Decision Tree
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/bryant_meng/article/details/85344607
收起
文章目录
1 GBDT概述
2 GBDT的负梯度拟合
3 GBDT回归算法
4 Demo
5 优缺点
【附录】GBDT和XGBoost的区别
参考
借鉴博客 GBDT原理与Sklearn源码分析-回归篇 (★★★★★)
1 GBDT概述
梯度提升树属于Boosting集成学习算法的一种,其思想不同于随机森林、Bagging的并行化、投票的流程,GBDT模型所输出的结果是由其包含的若干棵决策树累加而得到的,每一棵子决策树都是实现对先前决策树组预测残差的拟合,是对先前模型的结果的一种“修正”。梯度提升树既可以用于回归问题(此时被称为CART回归树),也可以被用于解决分类问题(GBDT分类树)。本文主要介绍GBDT回归的原理!
在GBDT的迭代中,假设我们前一轮迭代得到的强学习器是fm−1(x) f_{m−1}(x)f
m−1
(x), 损失函数是L(y,fm−1(x)) L(y,f_{m−1}(x))L(y,f
m−1
(x)), 我们本轮迭代的目标是找到一个CART回归树模型的弱学习器hm(x) h_{m}(x)h
m
(x),让本轮的损失L(y,fm(x))=L(y,fm−1(x)+hm(x)) L(y,f_{m}(x))=L(y,f_{m-1}(x)+h_{m}(x))L(y,f
m
(x))=L(y,f
m−1
(x)+h
m
(x))最小。也就是说,本轮迭代找到决策树,要让样本的损失尽量变得更小。
GBDT的思想可以用一个通俗的例子解释,假如有个人30岁,我们首先用20岁去拟合,发现损失有10岁,这时我们用6岁去拟合剩下的损失,发现差距还有4岁,第三轮我们用3岁拟合剩下的差距,差距就只有一岁了。如果我们的迭代轮数还没有完,可以继续迭代下面,每一轮迭代,拟合的岁数误差都会减小。
从上面的例子看这个思想还是蛮简单的,但是有个问题是这个损失的拟合不好度量,损失函数各种各样,怎么找到一种通用的拟合方法呢?
2 GBDT的负梯度拟合
在上一节中,我们介绍了GBDT的基本思路,但是没有解决损失函数拟合方法的问题。针对这个问题,大牛Freidman提出了用损失函数的负梯度来拟合本轮损失的近似值,进而拟合一个CART回归树。第m mm轮的第i ii个样本的损失函数的负梯度表示为
rim=−[∂L(yi,f(xi))∂f(xi)]f(x)=fm−1(x) r_{im}=-\left [ \frac{\partial L(y_{i},f(x_{i}))}{\partial f(x_{i})} \right ]_{f(x)=f_{m-1} (x)}
r
im
=−[
∂f(x
i
)
∂L(y
i
,f(x
i
))
]
f(x)=f
m−1
(x)
利用 (xi,rim),(i=1,2,..N) (x_{i},r_{im}),(i=1,2,..N)(x
i
,r
im
),(i=1,2,..N),我们可以拟合一颗CART回归树,得到了第 m mm 颗回归树,其对应的叶节点区域 Rjm,j=1,2,...,Jm R_{jm},j=1,2,...,J_{m}R
jm
,j=1,2,...,J
m
。其中Jm J_{m}J
m
为叶子节点的个数。
针对每一个叶子节点里的样本,我们求出使损失函数最小,也就是拟合叶子节点最好的的输出值γjm \gamma _{jm}γ
jm
如下:
γjm=argminγ∑xi∈RjmL(yi,fm−1(xi)+γ) \gamma _{jm} =\underset{\gamma}{arg\min}\sum_{x_{i}\in R_{jm}} L(y_{i},f_{m-1}(x_{i} )+\gamma)
γ
jm
=
γ
argmin
x
i
∈R
jm
∑
L(y
i
,f
m−1
(x
i
)+γ)
这样我们就得到了本轮的决策树拟合函数如下:
hm(x)=∑Jmj=1γjmI(x∈Rjm) h_{m}(x)=\sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm})
h
m
(x)=
j=1
∑
J
m
γ
jm
I(x∈R
jm
)
从而本轮最终得到的强学习器的表达式如下:
fm(x)=fm−1(x)+∑Jmj=1γjmI(x∈Rjm) f_{m}(x)=f_{m-1}(x) + \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm})
f
m
(x)=f
m−1
(x)+
j=1
∑
J
m
γ
jm
I(x∈R
jm
)
通过损失函数的负梯度来拟合,我们找到了一种通用的拟合损失误差的办法,这样无轮是分类问题还是回归问题,我们通过其损失函数的负梯度的拟合,就可以用GBDT来解决我们的分类回归问题。区别仅仅在于损失函数不同导致的负梯度不同而已。
3 GBDT回归算法
好了,有了上面的思路,下面我们总结下GBDT的回归算法。
输入:训练集样本{ (x1,y1),(x2,y2),...,(xN,yN) (x_{1},y_{1}),(x_{2},y_{2}),..., (x_{N},y_{N})(x
1
,y
1
),(x
2
,y
2
),...,(x
N
,y
N
)}, 最大迭代次数M MM, 损失函数L LL。
输出:强学习器 fˆ(x) \widehat{f}(x)
f
(x)
1) 初始化弱学习器
f0(x)=argminγ∑Ni=1L(yi,γ) f_{0}(x) = \underset{\gamma }{argmin}\sum_{i=1}^{N}L(y_{i},\gamma)
f
0
(x)=
γ
argmin
i=1
∑
N
L(y
i
,γ)
2) 对迭代轮数 m=1,2,...M m=1,2,...Mm=1,2,...M 有:
a) 对样本 i=1,2,...N i=1,2,...Ni=1,2,...N,计算负梯度
rim=−[∂L(yi,f(xi))∂f(xi)]f(x)=fm−1(x) r_{im}=-\left [ \frac{\partial L(y_{i},f(x_{i}))}{\partial f(x_{i})} \right ]_{f(x)=f_{m-1} (x)}
r
im
=−[
∂f(x
i
)
∂L(y
i
,f(x
i
))
]
f(x)=f
m−1
(x)
b) 利用 (xi,rim),(i=1,2,..N) (x_{i},r_{im}),(i=1,2,..N)(x
i
,r
im
),(i=1,2,..N),我们可以拟合一颗CART回归树,得到了第 m mm 颗回归树,其对应的叶节点区域 Rjm,j=1,2,...,Jm R_{jm},j=1,2,...,J_{m}R
jm
,j=1,2,...,J
m
。其中 Jm J_{m}J
m
为叶子节点的个数。
c) 对叶子区域 j=1,2,..Jm j =1,2,..J_{m}j=1,2,..J
m
,计算最佳拟合值
γjm=argminγ∑xi∈RjmL(yi,fm−1(xi)+γ) \gamma _{jm} =\underset{\gamma}{arg\min}\sum_{x_{i}\in R_{jm}} L(y_{i},f_{m-1}(x_{i} )+\gamma)
γ
jm
=
γ
argmin
x
i
∈R
jm
∑
L(y
i
,f
m−1
(x
i
)+γ)
d) 更新强学习器
fm(x)=fm−1(x)+∑Jmj=1γjmI(x∈Rjm) f_{m}(x)=f_{m-1}(x) + \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm})
f
m
(x)=f
m−1
(x)+
j=1
∑
J
m
γ
jm
I(x∈R
jm
)
3) 得到强学习器f(x)的表达式
fˆ(x)=fM(x)=f0(x)+∑Mm=1∑Jmj=1γjmI(x∈Rjm) \widehat{f}(x) = f_{M}(x)=f_{0}(x) + \sum_{m=1}^{M}\sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm})
f
(x)=f
M
(x)=f
0
(x)+
m=1
∑
M
j=1
∑
J
m
γ
jm
I(x∈R
jm
)
4 Demo
对于公式
rim=−[∂L(yi,f(xi))∂f(xi)]f(x)=fm−1(x) r_{im}=-\left [ \frac{\partial L(y_{i},f(x_{i}))}{\partial f(x_{i})} \right ]_{f(x)=f_{m-1} (x)}
r
im
=−[
∂f(x
i
)
∂L(y
i
,f(x
i
))
]
f(x)=f
m−1
(x)
当 loss function L(yi,f(xi))=12∗(yi−f(xi))2 L(y_{i},f(x_{i})) =\frac{1}{2}*(y_i-f(x_i))^2L(y
i
,f(x
i
))=
2
1
∗(y
i
−f(x
i
))
2
,也即是 Least-square 时,∂L(yi,f(xi))∂f(xi)=yi−f(xi) \frac{\partial L(y_{i},f(x_{i}))}{\partial f(x_{i})} = y_i-f(x_i)
∂f(x
i
)
∂L(y
i
,f(x
i
))
=y
i
−f(x
i
),代入当前模型f(x)=fm−1(x) f(x)=f_{m-1} (x)f(x)=f
m−1
(x),则有
∂L(yi,f(xi))∂f(xi)=yi−fm−1(xi) \frac{\partial L(y_{i},f(x_{i}))}{\partial f(x_{i})} = y_i-f_{m-1}(x_i)
∂f(x
i
)
∂L(y
i
,f(x
i
))
=y
i
−f
m−1
(x
i
)
所以我们能看到,当损失函数选用 Least-square 时,每一次拟合的值就是(真实值-当前模型的值)。
【其它 loss function 的形式请参考 GBDT原理与Sklearn源码分析-回归篇 (★★★★★)】
对于初始化弱分类器 f0(x) f_{0}(x)f
0
(x)
f0(x)=argminγ∑Ni=1L(yi,γ) f_{0}(x) = \underset{\gamma }{argmin}\sum_{i=1}^{N}L(y_{i},\gamma)
f
0
(x)=
γ
argmin
i=1
∑
N
L(y
i
,γ)
为什么需要初始化?很简单,因为每次在计算负梯度值时需要用到前一个模型 fm−1(xi) f_{m−1}(x_i)f
m−1
(x
i
) 预测的值。对于我们训练的第一个模型 m=1 m=1m=1 而言需要有 f0(xi) f_0(x_i)f
0
(x
i
) 的存在。那么 f0(x) f_0(x)f
0
(x) 初始化为多少?这个取决于loss function的选择,当 loss function 选择 MSE 时:
f0(x)=y¯ f_0(x) = \bar{y}
f
0
(x)=
y
ˉ
【其它 loss function 的形式请参考 GBDT原理与Sklearn源码分析-回归篇 (★★★★★)】
对叶子区域 j=1,2,..Jm j =1,2,..J_{m}j=1,2,..J
m
,计算最佳拟合值
γjm=argminγ∑xi∈RjmL(yi,fm−1(xi)+γ) \gamma _{jm} =\underset{\gamma}{arg\min}\sum_{x_{i}\in R_{jm}} L(y_{i},f_{m-1}(x_{i} )+\gamma)
γ
jm
=
γ
argmin
x
i
∈R
jm
∑
L(y
i
,f
m−1
(x
i
)+γ)
那么叶子节点的取值为多少?也就是这颗树到底输出多少? 在Friedman的论文中有这部分的推导。这里简单总结一下,叶子节点的取值和所选择的loss function有关。对于不同的Loss function,叶子节点的值也不一样。比如选择 MSE 作为 loss function 时:
γjm=avexi∈Rjm(yi−fm−1(xi)) \gamma _{jm} = ave_{x_{i}\in R_{jm}}\left ( y_i - f_{m-1}\left ( x_i \right ) \right )
γ
jm
=ave
x
i
∈R
jm
(y
i
−f
m−1
(x
i
))
【其它 loss function 的形式请参考 GBDT原理与Sklearn源码分析-回归篇 (★★★★★)】
掌握了以上技巧,我们下面来试试一个小例子
xi x_ix
i
1 2 3 4 5 6 7 8 9 10
yi y_iy
i
5.56 5.7 5.91 6.4 6.8 7.05 8.9 8.7 9 9.05
1)选择 MSE 做为建树的分裂准则
2)选择 MSE 作为误差函数
3)树的深度设置为1
初始化弱学习器
f0(x)=y¯=7.307 f_0(x) = \bar{y} =7.307
f
0
(x)=
y
ˉ
=7.307
拟合第一颗树(m=1 m=1m=1)
rim=−[∂L(yi,f(xi))∂f(xi)]f(x)=fm−1(x)=yi−fm−1(xi)=yi−f0(xi) r_{im}=-\left [ \frac{\partial L(y_{i},f(x_{i}))}{\partial f(x_{i})} \right ]_{f(x)=f_{m-1} (x)}=y_i-f_{m-1}(x_i)=y_i-f_{0}(x_i)
r
im
=−[
∂f(x
i
)
∂L(y
i
,f(x
i
))
]
f(x)=f
m−1
(x)
=y
i
−f
m−1
(x
i
)=y
i
−f
0
(x
i
)
利用 (xi,rim),(i=1,2,..N) (x_{i},r_{im}),(i=1,2,..N)(x
i
,r
im
),(i=1,2,..N),我们可以拟合一颗CART回归树。
xi x_ix
i
1 2 3 4 5 6 7 8 9 10
ri1 r_{i1}r
i1
-1.747 -1.607 -1.397 -0.907 -0.507 -0.257 1.593 1.393 1.693 1.743
这里简单介绍一下决策树建树的过程:
决策树学习最关键的步骤就是选择最优划分属性,一般而言,随着划分不过程不断的进行,我们希望决策树的分支节点所包含的样本尽可能属于同一类别(方差小)。通常,我们会选择一个准则来评价划分的质量,比如回归树中经常使用的 MSE(这种方法属于启发式的)
对于连续值,我们可以穷尽每个值 v vv,把每个值 v vv 作为一个分裂点(≤v \leq v≤v 和 >v > v>v),然后计算两个分支的MSEleft MSE_{left}MSE
left
、MSEright MSE_{right}MSE
right
,选择最小的MSEsum=MSEleft+MSEright MSE_{sum} = MSE_{left} + MSE_{right}MSE
sum
=MSE
left
+MSE
right
的分裂点 v vv
选不同 xi x_ix
i
(x1−x9 x_1-x_9x
1
−x
9
)做为分裂点的结果如下:
[1.7470098765432096, 1.5140984375000002, 1.2069133786848074,
0.99636875000000047, 0.78226400000000029, 0.32765763888888899,
1.1579092970521545, 1.4673937500000001, 1.748733333333333]
1
2
3
可以得到当选择 6 作为分裂点时 MSEsum=0.3276 MSE_{sum} = 0.3276MSE
sum
=0.3276 最小
得到了第 m mm 颗回归树,其对应的叶节点区域 Rjm,j=1,2,...,Jm R_{jm},j=1,2,...,J_{m}R
jm
,j=1,2,...,J
m
。其中 Jm J_{m}J
m
为叶子节点的个数
落地为:得到了第 1 11 颗回归树,其对应的叶节点区域 Rj1,j=1,2 R_{j1},j=1,2R
j1
,j=1,2。
R11 R_{11}R
11
为 x1−x6 x_1-x_6x
1
−x
6
R21 R_{21}R
21
为 x7−x10 x_7-x_{10}x
7
−x
10
γ11=r11¯¯¯¯¯+r21¯¯¯¯¯+r31¯¯¯¯¯+r41¯¯¯¯¯+r51¯¯¯¯¯+r61¯¯¯¯¯6=−1.0703 \gamma_{11}=\frac{\bar{r_{11}}+ \bar{r_{21}} + \bar{r_{31}}+\bar{r_{41}}+ \bar{r_{51}}+\bar{r_{61}}}{6} = -1.0703
γ
11
=
6
r
11
ˉ
+
r
21
ˉ
+
r
31
ˉ
+
r
41
ˉ
+
r
51
ˉ
+
r
61
ˉ
=−1.0703
γ21=r71¯¯¯¯¯+r81¯¯¯¯¯+r91¯¯¯¯¯6=1.6055 \gamma_{21}=\frac{\bar{r_{71}}+\bar{r_{81}}+\bar{r_{91}}}{6} =1.6055
γ
21
=
6
r
71
ˉ
+
r
81
ˉ
+
r
91
ˉ
=1.6055
更新强学习器
fm(x)=fm−1(x)+∑Jmj=1γjmI(x∈Rjm) f_{m}(x)=f_{m-1}(x) + \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm})
f
m
(x)=f
m−1
(x)+
j=1
∑
J
m
γ
jm
I(x∈R
jm
)
落地为,更新 f1(xi) f_1(x_i)f
1
(x
i
)
f1(xi)=f0(xi)+∑2j=1γj1I(xi∈Rj1) f_1(x_i) = f_0(x_i) + \sum_{j=1}^{2}\gamma_{j1}I(x_i\in R_{j1})
f
1
(x
i
)=f
0
(x
i
)+
j=1
∑
2
γ
j1
I(x
i
∈R
j1
)
例如更新 x1 x_1x
1
的预测值,x1 x_1x
1
落在 R11 R_{11}R
11
,对应 γ11 \gamma_{11}γ
11
,f1(x1)=f0(x1)+γ11=7.307−1.0703=6.2367 f_1(x_1) = f_0(x_1) + \gamma_{11} = 7.307 - 1.0703 = 6.2367f
1
(x
1
)=f
0
(x
1
)+γ
11
=7.307−1.0703=6.2367
在GBDT里,我们通常不会直接把上一个轮的预测值 fm−1(x) f_{m-1}(x)f
m−1
(x) 直接加上 ∑Jmj=1γjmI(x∈Rjm) \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm})∑
j=1
J
m
γ
jm
I(x∈R
jm
),而是会在 ∑Jmj=1γjmI(x∈Rjm) \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm})∑
j=1
J
m
γ
jm
I(x∈R
jm
) 上乘上一个学习率,可以理解,因为如果每次完全加上(学习率为1)本轮模型的预测值容易导致过拟合。所以通常在GBDT中的做法(也叫Shrinkage)是:
fm(x)=fm−1(x)+η∑Jmj=1γjmI(x∈Rjm) f_{m}(x)=f_{m-1}(x) + \eta \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm})
f
m
(x)=f
m−1
(x)+η
j=1
∑
J
m
γ
jm
I(x∈R
jm
)
η \etaη 为学习率,所以,当η=0.1 \eta=0.1η=0.1时,上面的计算结果变为
f1(x1)=f0(x1)+0.1∗γ11=7.307−0.10703=7.19997 f_1(x_1) = f_0(x_1) +0.1 * \gamma_{11} = 7.307 - 0.10703 = 7.19997
f
1
(x
1
)=f
0
(x
1
)+0.1∗γ
11
=7.307−0.10703=7.19997
所有样本的更新结果如下,也即是强学习 f1(x) f_1(x)f
1
(x):
[7.1999666666666666, 7.1999666666666666, 7.1999666666666666,
7.1999666666666666, 7.1999666666666666, 7.1999666666666666,
7.4675500000000001, 7.4675500000000001, 7.4675500000000001,
7.4675500000000001]
1
2
3
4
至此一轮迭代(第一个颗树拟合)完成,下面开始第二轮迭代(第二颗树拟合)。
强学习 f1(x) f_1(x)f
1
(x)
[7.1999666666666666, 7.1999666666666666, 7.1999666666666666,
7.1999666666666666, 7.1999666666666666, 7.1999666666666666,
7.4675500000000001, 7.4675500000000001, 7.4675500000000001,
7.4675500000000001]
1
2
3
4
拟合第二颗树(m=2 m=2m=2)
rim=−[∂L(yi,f(xi))∂f(xi)]f(x)=fm−1(x)=yi−fm−1(xi)=yi−f1(xi) r_{im}=-\left [ \frac{\partial L(y_{i},f(x_{i}))}{\partial f(x_{i})} \right ]_{f(x)=f_{m-1} (x)}=y_i-f_{m-1}(x_i)=y_i-f_{1}(x_i)
r
im
=−[
∂f(x
i
)
∂L(y
i
,f(x
i
))
]
f(x)=f
m−1
(x)
=y
i
−f
m−1
(x
i
)=y
i
−f
1
(x
i
)
利用 (xi,rim),(i=1,2,..N) (x_{i},r_{im}),(i=1,2,..N)(x
i
,r
im
),(i=1,2,..N),我们可以拟合一颗CART回归树。
xi x_ix
i
1 2 3 4 5 6 7 8 9 10
ri2 r_{i2}r
i2
-1.63996667 -1.49996667 -1.28996667 -0.79996667 -0.39996667 -0.14996667 1.43245 1.23245 1.53245 1.58245
[-1.639966666666667, -1.4999666666666664, -1.2899666666666665,
-0.79996666666666627, -0.3999666666666668, -0.1499666666666668,
1.4324500000000002, 1.2324499999999992, 1.5324499999999999,
1.5824500000000006]
1
2
3
4
决策树的构建
选不同 xi x_ix
i
(x1−x9 x_1-x_9x
1
−x
9
)做为分裂点的结果如下:
1.4289876354595334, 1.2145779184027778, 0.94102838038548786,
0.7759147700617286, 0.63424046777777798, 0.32765763888888905,
0.9921468829365081, 1.2236044283854166, 1.451869445987654
1
2
3
可以得到当选择 6 作为分裂点时 MSEsum MSE_{sum}MSE
sum
最小
得到了第 m mm 颗回归树,其对应的叶节点区域 Rjm,j=1,2,...,Jm R_{jm},j=1,2,...,J_{m}R
jm
,j=1,2,...,J
m
。其中 Jm J_{m}J
m
为叶子节点的个数
落地为:得到了第 2 22 颗回归树,其对应的叶节点区域 Rj2,j=1,2 R_{j2},j=1,2R
j2
,j=1,2。
R12 R_{12}R
12
为 x1−x6 x_1-x_6x
1
−x
6
R22 R_{22}R
22
为 x7−x10 x_7-x_{10}x
7
−x
10
γ12=r12¯¯¯¯¯+r22¯¯¯¯¯+r32¯¯¯¯¯+r42¯¯¯¯¯+r52¯¯¯¯¯+r62¯¯¯¯¯6=−0.9633 \gamma_{12}=\frac{\bar{r_{12}}+ \bar{r_{22}} + \bar{r_{32}}+\bar{r_{42}}+ \bar{r_{52}}+\bar{r_{62}}}{6} = -0.9633
γ
12
=
6
r
12
ˉ
+
r
22
ˉ
+
r
32
ˉ
+
r
42
ˉ
+
r
52
ˉ
+
r
62
ˉ
=−0.9633
γ22=r72¯¯¯¯¯+r82¯¯¯¯¯+r92¯¯¯¯¯6=1.44495 \gamma_{22}=\frac{\bar{r_{72}}+\bar{r_{82}}+\bar{r_{92}}}{6} =1.44495
γ
22
=
6
r
72
ˉ
+
r
82
ˉ
+
r
92
ˉ
=1.44495
更新强学习器
fm(x)=fm−1(x)+∑Jmj=1γjmI(x∈Rjm) f_{m}(x)=f_{m-1}(x) + \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm})
f
m
(x)=f
m−1
(x)+
j=1
∑
J
m
γ
jm
I(x∈R
jm
)
落地为,更新 f2(xi) f_2(x_i)f
2
(x
i
)
f2(xi)=f1(xi)+∑2j=1γj2I(xi∈Rj2) f_2(x_i) = f_1(x_i) + \sum_{j=1}^{2}\gamma_{j2}I(x_i\in R_{j2})
f
2
(x
i
)=f
1
(x
i
)+
j=1
∑
2
γ
j2
I(x
i
∈R
j2
)
例如更新 x1 x_1x
1
的预测值,x1 x_1x
1
落在 R12 R_{12}R
12
f2(x1)=f1(x1)+0.1∗γ12=7.19996+0.1∗(−0.9633)=7.10363 f_2(x_1) = f_1(x_1) +0.1 * \gamma_{12} = 7.19996 +0.1*(-0.9633) = 7.10363
f
2
(x
1
)=f
1
(x
1
)+0.1∗γ
12
=7.19996+0.1∗(−0.9633)=7.10363
所有样本的更新结果如下,也即是强学习 f2(x) f_2(x)f
2
(x):
[7.1036366666666666, 7.1036366666666666, 7.1036366666666666,
7.1036366666666666, 7.1036366666666666, 7.1036366666666666,
7.6120450000000002, 7.6120450000000002, 7.6120450000000002,
7.6120450000000002]
1
2
3
4
当只有两颗树的时候,f2(x) f_2(x)f
2
(x)即为预测的结果。
如果多颗树的话,拟合残差的过程如下:
计算上列过程的代码如下
import numpy as np
# 用 MSE 算最优分裂点
def MSE(residual):
mse = []
for i in range(1,len(residual)):
mse.append(np.var(residual[:i])+ np.var(residual[i:]))
print('mse:',mse,'\n')
split = mse.index(min(mse))+1
print('split:',split)
r1 = np.mean(residual[:mse.index(min(mse))+1])
r2 = np.mean(residual[mse.index(min(mse))+1:])
return r1,r2,split
1
2
3
4
5
6
7
8
9
10
11
12
两棵树,深度为1的计算过程
y = [5.56,5.7,5.91,6.4,6.8,7.05,8.9,8.7,9,9.05]
print('y:',y,'\n')
F0 = np.average(y)
print('F0:',F0,'\n')
residual = y - F0
print("residual:",residual,'\n')
r11,r21,split = MSE(residual)
print('r11:',r11)
print('r21:',r21,'\n')
# F1
F1 = []
for i in range(0,10):
if i<split:
F1.append(F0+0.1*r11) # learning rate 0.1
else:
F1.append(F0+0.1*r21)
print('F1:',F1,'\n')
residual2 = list(np.array(y) - np.array(F1))
print("residual2:",residual2,'\n')
r12,r22,split = MSE(residual2)
print('r12:',r12)
print('r22:',r22,'\n')
# F2
F2 = []
for i in range(0,10):
if i<split:
F2.append(F1[i]+0.1*r12) # learning rate 0.1
else:
F2.append(F1[i]+0.1*r22)
print('F2:',F2,'\n')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
output
y: [5.56, 5.7, 5.91, 6.4, 6.8, 7.05, 8.9, 8.7, 9, 9.05]
F0: 7.307
residual: [-1.747 -1.607 -1.397 -0.907 -0.507 -0.257 1.593 1.393 1.693 1.743]
mse: [1.7470098765432096, 1.5140984375000002, 1.2069133786848074, 0.99636875000000047, 0.78226400000000029, 0.32765763888888899, 1.1579092970521545, 1.4673937500000001, 1.748733333333333]
split: 6
r11: -1.07033333333
r21: 1.6055
F1: [7.1999666666666666, 7.1999666666666666, 7.1999666666666666, 7.1999666666666666, 7.1999666666666666, 7.1999666666666666, 7.4675500000000001, 7.4675500000000001, 7.4675500000000001, 7.4675500000000001]
residual2: [-1.639966666666667, -1.4999666666666664, -1.2899666666666665, -0.79996666666666627, -0.3999666666666668, -0.1499666666666668, 1.4324500000000002, 1.2324499999999992, 1.5324499999999999, 1.5824500000000006]
mse: [1.4289876354595334, 1.2145779184027778, 0.94102838038548786, 0.7759147700617286, 0.63424046777777798, 0.32765763888888905, 0.9921468829365081, 1.2236044283854166, 1.451869445987654]
split: 6
r12: -0.9633
r22: 1.44495
F2: [7.1036366666666666, 7.1036366666666666, 7.1036366666666666, 7.1036366666666666, 7.1036366666666666, 7.1036366666666666, 7.6120450000000002, 7.6120450000000002, 7.6120450000000002, 7.6120450000000002]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
【Scikit-learn源码分析请参考 GBDT原理与Sklearn源码分析-回归篇 (★★★★★)】
5 优缺点
1)优点:
可以灵活处理各种类型的数据,包括连续值和离散值。
在相对少的调参时间情况下,预测的准备率也可以比较高。这个是相对SVM来说的。
使用一些健壮的损失函数,对异常值的鲁棒性非常强。比如 Huber损失函数和Quantile损失函数。
2)缺点:
由于弱学习器之间存在依赖关系,难以并行训练数据。不过可以通过自采样的SGBT来达到部分并行。
【附录】GBDT和XGBoost的区别
1) GBDT是机器学习算法,XGBoost是该算法的工程实现
2) XGBoost 加入了正则项
3) GBDT只用了 cost function 的一阶导信息,XGBoost 对 cost fucntion 进行了泰勒展开,可同时使用一阶和二阶导
4) 传统 GBDT 用 CART作为基分类器,XGBoost 支持多种基分类器,比如线性分类器
5) 传统的 GBDT每次迭代使用所有的数据,XGBoost 采用了与随机森林相似的策略,支持对数据进行采样
6) 传统的 GBDT 没有设置对缺损值的处理,XGBoost 能自动的学习出缺失值的处理策略
参考
【1】 自我代码提升之梯度提升树
【2】干货|从零开始学习Gradient Boosting算法
【3】 梯度提升树(GBDT)原理小结
【4】 30分钟学会用scikit-learn的基本回归方法(线性、决策树、SVM、KNN)和集成方法(随机森林,Adaboost和GBRT)
【5】A Kaggle Master Explains Gradient Boosting
【6】结合Scikit-learn介绍几种常用的特征选择方法
【7】scikit-learn 梯度提升树(GBDT)调参小结
【8】scikit-learn (sklearn) 官方文档中文版
【9】scikit-learn (sklearn) 官方文档
【10】GBDT算法原理以及实例理解(★★★★)
【11】GBDT原理与Sklearn源码分析-回归篇 (★★★★★)
【12】GBDT源码剖析
【13】sklearn.ensemble.GradientBoostingRegressor
————————————————
版权声明:本文为CSDN博主「bryant_meng」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bryant_meng/article/details/85344607