Gradient Boosting Decision Tree


借鉴博客 GBDT原理与Sklearn源码分析-回归篇 (★★★★★)


1 GBDT概述

  梯度提升树属于Boosting集成学习算法的一种,其思想不同于随机森林、Bagging的并行化、投票的流程,GBDT模型所输出的结果是由其包含的若干棵决策树累加而得到的,每一棵子决策树都是实现对先前决策树组预测残差的拟合,是对先前模型的结果的一种“修正”。梯度提升树既可以用于回归问题(此时被称为CART回归树),也可以被用于解决分类问题(GBDT分类树)。本文主要介绍GBDT回归的原理!

  在GBDT的迭代中,假设我们前一轮迭代得到的强学习器 f m − 1 ( x ) f_{m−1}(x) fm1(x), 损失函数 L ( y , f m − 1 ( x ) ) L(y,f_{m−1}(x)) L(y,fm1(x)), 我们本轮迭代的目标是找到一个CART回归树模型的弱学习器 h m ( x ) h_{m}(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)) L(y,fm(x))=L(y,fm1(x)+hm(x))最小。也就是说,本轮迭代找到决策树,要让样本的损失尽量变得更小。

  GBDT的思想可以用一个通俗的例子解释,假如有个人30岁,我们首先用20岁去拟合,发现损失有10岁,这时我们用6岁去拟合剩下的损失,发现差距还有4岁,第三轮我们用3岁拟合剩下的差距,差距就只有一岁了。如果我们的迭代轮数还没有完,可以继续迭代下面,每一轮迭代,拟合的岁数误差都会减小。

  从上面的例子看这个思想还是蛮简单的,但是有个问题是这个损失的拟合不好度量,损失函数各种各样,怎么找到一种通用的拟合方法呢?

2 GBDT的负梯度拟合

这里写图片描述

  在上一节中,我们介绍了GBDT的基本思路,但是没有解决损失函数拟合方法的问题。针对这个问题,大牛Freidman提出了用损失函数的负梯度来拟合本轮损失的近似值,进而拟合一个CART回归树。第 m m m轮的第 i i i个样本的损失函数的负梯度表示为
r i m = − [ ∂ L ( y i , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) r_{im}=-\left [ \frac{\partial L(y_{i},f(x_{i}))}{\partial f(x_{i})} \right ]_{f(x)=f_{m-1} (x)} rim=[f(xi)L(yi,f(xi))]f(x)=fm1(x)

  利用 ( x i , r i m ) , ( i = 1 , 2 , . . N ) (x_{i},r_{im}),(i=1,2,..N) (xi,rim),(i=1,2,..N),我们可以拟合一颗CART回归树,得到了第 m m m 颗回归树,其对应的叶节点区域 R j m , j = 1 , 2 , . . . , J m R_{jm},j=1,2,...,J_{m} Rjm,j=1,2,...,Jm。其中 J m J_{m} Jm 为叶子节点的个数。

  针对每一个叶子节点里的样本,我们求出使损失函数最小,也就是拟合叶子节点最好的的输出值 γ j m \gamma _{jm} γjm如下:
γ j m = a r g min ⁡ γ ∑ x i ∈ R j m L ( y i , f m − 1 ( x i ) + γ ) \gamma _{jm} =\underset{\gamma}{arg\min}\sum_{x_{i}\in R_{jm}} L(y_{i},f_{m-1}(x_{i} )+\gamma) γjm=γargminxiRjmL(yi,fm1(xi)+γ)

  这样我们就得到了本轮的决策树拟合函数如下:
h m ( x ) = ∑ j = 1 J m γ j m I ( x ∈ R j m ) h_{m}(x)=\sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm}) hm(x)=j=1JmγjmI(xRjm)

  从而本轮最终得到的强学习器的表达式如下:
f m ( x ) = f m − 1 ( x ) + ∑ j = 1 J m γ j m I ( x ∈ R j m ) f_{m}(x)=f_{m-1}(x) + \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm}) fm(x)=fm1(x)+j=1JmγjmI(xRjm)

  通过损失函数的负梯度来拟合,我们找到了一种通用的拟合损失误差的办法,这样无轮是分类问题还是回归问题,我们通过其损失函数的负梯度的拟合,就可以用GBDT来解决我们的分类回归问题。区别仅仅在于损失函数不同导致的负梯度不同而已。

3 GBDT回归算法

  好了,有了上面的思路,下面我们总结下GBDT的回归算法。
  输入:训练集样本{ ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) (x_{1},y_{1}),(x_{2},y_{2}),..., (x_{N},y_{N}) (x1,y1),(x2,y2),...,(xN,yN)}, 最大迭代次数 M M M, 损失函数 L L L
  输出:强学习器 f ^ ( x ) \widehat{f}(x) f (x)
这里写图片描述

  1) 初始化弱学习器
f 0 ( x ) = a r g m i n γ ∑ i = 1 N L ( y i , γ ) f_{0}(x) = \underset{\gamma }{argmin}\sum_{i=1}^{N}L(y_{i},\gamma) f0(x)=γargmini=1NL(yi,γ)

  2) 对迭代轮数 m = 1 , 2 , . . . M m=1,2,...M m=1,2,...M
    a) 对样本 i = 1 , 2 , . . . N i=1,2,...N i=1,2...N,计算负梯度
r i m = − [ ∂ L ( y i , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) r_{im}=-\left [ \frac{\partial L(y_{i},f(x_{i}))}{\partial f(x_{i})} \right ]_{f(x)=f_{m-1} (x)} rim=[f(xi)L(yi,f(xi))]f(x)=fm1(x)

    b) 利用 ( x i , r i m ) , ( i = 1 , 2 , . . N ) (x_{i},r_{im}),(i=1,2,..N) (xi,rim),(i=1,2,..N),我们可以拟合一颗CART回归树,得到了第 m m m 颗回归树,其对应的叶节点区域 R j m , j = 1 , 2 , . . . , J m R_{jm},j=1,2,...,J_{m} Rjm,j=1,2,...,Jm。其中 J m J_{m} Jm 为叶子节点的个数。

    c) 对叶子区域 j = 1 , 2 , . . J m j =1,2,..J_{m} j=1,2,..Jm,计算最佳拟合值
γ j m = a r g min ⁡ γ ∑ x i ∈ R j m L ( y i , f m − 1 ( x i ) + γ ) \gamma _{jm} =\underset{\gamma}{arg\min}\sum_{x_{i}\in R_{jm}} L(y_{i},f_{m-1}(x_{i} )+\gamma) γjm=γargminxiRjmL(yi,fm1(xi)+γ)
    d) 更新强学习器
f m ( x ) = f m − 1 ( x ) + ∑ j = 1 J m γ j m I ( x ∈ R j m ) f_{m}(x)=f_{m-1}(x) + \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm}) fm(x)=fm1(x)+j=1JmγjmI(xRjm)

  3) 得到强学习器f(x)的表达式
f ^ ( x ) = f M ( x ) = f 0 ( x ) + ∑ m = 1 M ∑ j = 1 J m γ j m I ( x ∈ R j m ) \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)=fM(x)=f0(x)+m=1Mj=1JmγjmI(xRjm)

4 Demo

  • 对于公式 r i m = − [ ∂ L ( y i , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) r_{im}=-\left [ \frac{\partial L(y_{i},f(x_{i}))}{\partial f(x_{i})} \right ]_{f(x)=f_{m-1} (x)} rim=[f(xi)L(yi,f(xi))]f(x)=fm1(x)
    当 loss function L ( y i , f ( x i ) ) = 1 2 ∗ ( y i − f ( x i ) ) 2 L(y_{i},f(x_{i})) =\frac{1}{2}*(y_i-f(x_i))^2 L(yi,f(xi))=21(yif(xi))2,也即是 Least-square 时, ∂ L ( y i , f ( x i ) ) ∂ f ( x i ) = y i − f ( x i ) \frac{\partial L(y_{i},f(x_{i}))}{\partial f(x_{i})} = y_i-f(x_i) f(xi)L(yi,f(xi))=yif(xi),代入当前模型 f ( x ) = f m − 1 ( x ) f(x)=f_{m-1} (x) f(x)=fm1(x),则有 ∂ L ( y i , f ( x i ) ) ∂ f ( x i ) = y i − f m − 1 ( x i ) \frac{\partial L(y_{i},f(x_{i}))}{\partial f(x_{i})} = y_i-f_{m-1}(x_i) f(xi)L(yi,f(xi))=yifm1(xi)所以我们能看到,当损失函数选用 Least-square 时,每一次拟合的值就是(真实值-当前模型的值)。
    【其它 loss function 的形式请参考 GBDT原理与Sklearn源码分析-回归篇 (★★★★★)】

  • 对于初始化弱分类器 f 0 ( x ) f_{0}(x) f0(x)
    f 0 ( x ) = a r g m i n γ ∑ i = 1 N L ( y i , γ ) f_{0}(x) = \underset{\gamma }{argmin}\sum_{i=1}^{N}L(y_{i},\gamma) f0(x)=γargmini=1NL(yi,γ)
    为什么需要初始化?很简单,因为每次在计算负梯度值时需要用到前一个模型 f m − 1 ( x i ) f_{m−1}(x_i) fm1(xi) 预测的值。对于我们训练的第一个模型 m = 1 m=1 m=1 而言需要有 f 0 ( x i ) f_0(x_i) f0(xi) 的存在。那么 f 0 ( x ) f_0(x) f0(x) 初始化为多少?这个取决于loss function的选择,当 loss function 选择 MSE 时: f 0 ( x ) = y ˉ f_0(x) = \bar{y} f0(x)=yˉ
    【其它 loss function 的形式请参考 GBDT原理与Sklearn源码分析-回归篇 (★★★★★)】

  • 对叶子区域 j = 1 , 2 , . . J m j =1,2,..J_{m} j=1,2,..Jm,计算最佳拟合值
    γ j m = a r g min ⁡ γ ∑ x i ∈ R j m L ( y i , f m − 1 ( x i ) + γ ) \gamma _{jm} =\underset{\gamma}{arg\min}\sum_{x_{i}\in R_{jm}} L(y_{i},f_{m-1}(x_{i} )+\gamma) γjm=γargminxiRjmL(yi,fm1(xi)+γ)
    那么叶子节点的取值为多少?也就是这颗树到底输出多少? 在Friedman的论文中有这部分的推导。这里简单总结一下,叶子节点的取值和所选择的loss function有关。对于不同的Loss function,叶子节点的值也不一样。比如选择 MSE 作为 loss function 时:
    γ j m = a v e x i ∈ R j m ( y i − f m − 1 ( x i ) ) \gamma _{jm} = ave_{x_{i}\in R_{jm}}\left ( y_i - f_{m-1}\left ( x_i \right ) \right ) γjm=avexiRjm(yifm1(xi))
    【其它 loss function 的形式请参考 GBDT原理与Sklearn源码分析-回归篇 (★★★★★)】

掌握了以上技巧,我们下面来试试一个小例子

x i x_i xi12345678910
y i y_i yi5.565.75.916.46.87.058.98.799.05

1)选择 MSE 做为建树的分裂准则
2)选择 MSE 作为误差函数
3)树的深度设置为1

  • 初始化弱学习器 f 0 ( x ) = y ˉ = 7.307 f_0(x) = \bar{y} =7.307 f0(x)=yˉ=7.307

  • 拟合第一颗树( m = 1 m=1 m=1 r i m = − [ ∂ L ( y i , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) = y i − f m − 1 ( x i ) = y i − f 0 ( x i ) 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) rim=[f(xi)L(yi,f(xi))]f(x)=fm1(x)=yifm1(xi)=yif0(xi)

  • 利用 ( x i , r i m ) , ( i = 1 , 2 , . . N ) (x_{i},r_{im}),(i=1,2,..N) (xi,rim),(i=1,2,..N),我们可以拟合一颗CART回归树。

x i x_i xi12345678910
r i 1 r_{i1} ri1-1.747-1.607-1.397-0.907-0.507-0.2571.5931.3931.6931.743

这里简单介绍一下决策树建树的过程:

决策树学习最关键的步骤就是选择最优划分属性,一般而言,随着划分不过程不断的进行,我们希望决策树的分支节点所包含的样本尽可能属于同一类别(方差小)。通常,我们会选择一个准则来评价划分的质量,比如回归树中经常使用的 MSE(这种方法属于启发式的)

对于连续值,我们可以穷尽每个值 v v v,把每个值 v v v 作为一个分裂点( ≤ v \leq v v > v > v >v),然后计算两个分支的 M S E l e f t MSE_{left} MSEleft M S E r i g h t MSE_{right} MSEright,选择最小的 M S E s u m = M S E l e f t + M S E r i g h t MSE_{sum} = MSE_{left} + MSE_{right} MSEsum=MSEleft+MSEright 的分裂点 v v v
选不同 x i x_i xi x 1 − x 9 x_1-x_9 x1x9)做为分裂点的结果如下:

[1.7470098765432096, 1.5140984375000002, 1.2069133786848074, 
0.99636875000000047, 0.78226400000000029, 0.32765763888888899, 
1.1579092970521545, 1.4673937500000001, 1.748733333333333] 

可以得到当选择 6 作为分裂点时 M S E s u m = 0.3276 MSE_{sum} = 0.3276 MSEsum=0.3276 最小
在这里插入图片描述

  • 得到了第 m m m 颗回归树,其对应的叶节点区域 R j m , j = 1 , 2 , . . . , J m R_{jm},j=1,2,...,J_{m} Rjm,j=1,2,...,Jm。其中 J m J_{m} Jm 为叶子节点的个数
    落地为:得到了第 1 1 1 颗回归树,其对应的叶节点区域 R j 1 , j = 1 , 2 R_{j1},j=1,2 Rj1,j=1,2
    R 11 R_{11} R11 x 1 − x 6 x_1-x_6 x1x6
    R 21 R_{21} R21 x 7 − x 10 x_7-x_{10} x7x10
    γ 11 = r 11 ˉ + r 21 ˉ + r 31 ˉ + r 41 ˉ + r 51 ˉ + r 61 ˉ 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=6r11ˉ+r21ˉ+r31ˉ+r41ˉ+r51ˉ+r61ˉ=1.0703
    γ 21 = r 71 ˉ + r 81 ˉ + r 91 ˉ 6 = 1.6055 \gamma_{21}=\frac{\bar{r_{71}}+\bar{r_{81}}+\bar{r_{91}}}{6} =1.6055 γ21=6r71ˉ+r81ˉ+r91ˉ=1.6055

  • 更新强学习器
    f m ( x ) = f m − 1 ( x ) + ∑ j = 1 J m γ j m I ( x ∈ R j m ) f_{m}(x)=f_{m-1}(x) + \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm}) fm(x)=fm1(x)+j=1JmγjmI(xRjm)
    落地为,更新 f 1 ( x i ) f_1(x_i) f1(xi)
    f 1 ( x i ) = f 0 ( x i ) + ∑ j = 1 2 γ j 1 I ( x i ∈ R j 1 ) f_1(x_i) = f_0(x_i) + \sum_{j=1}^{2}\gamma_{j1}I(x_i\in R_{j1}) f1(xi)=f0(xi)+j=12γj1I(xiRj1)
    例如更新 x 1 x_1 x1 的预测值, x 1 x_1 x1 落在 R 11 R_{11} R11,对应 γ 11 \gamma_{11} γ11 f 1 ( x 1 ) = f 0 ( x 1 ) + γ 11 = 7.307 − 1.0703 = 6.2367 f_1(x_1) = f_0(x_1) + \gamma_{11} = 7.307 - 1.0703 = 6.2367 f1(x1)=f0(x1)+γ11=7.3071.0703=6.2367
    在GBDT里,我们通常不会直接把上一个轮的预测值 f m − 1 ( x ) f_{m-1}(x) fm1(x) 直接加上 ∑ j = 1 J m γ j m I ( x ∈ R j m ) \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm}) j=1JmγjmI(xRjm),而是会在 ∑ j = 1 J m γ j m I ( x ∈ R j m ) \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm}) j=1JmγjmI(xRjm) 上乘上一个学习率,可以理解,因为如果每次完全加上(学习率为1)本轮模型的预测值容易导致过拟合。所以通常在GBDT中的做法(也叫Shrinkage)是: f m ( x ) = f m − 1 ( x ) + η ∑ j = 1 J m γ j m I ( x ∈ R j m ) f_{m}(x)=f_{m-1}(x) + \eta \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm}) fm(x)=fm1(x)+ηj=1JmγjmI(xRjm)
    η \eta η 为学习率,所以,当 η = 0.1 \eta=0.1 η=0.1时,上面的计算结果变为
    f 1 ( x 1 ) = f 0 ( x 1 ) + 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 f1(x1)=f0(x1)+0.1γ11=7.3070.10703=7.19997

    所有样本的更新结果如下,也即是强学习 f 1 ( x ) f_1(x) f1(x)

[7.1999666666666666, 7.1999666666666666, 7.1999666666666666, 
7.1999666666666666, 7.1999666666666666, 7.1999666666666666, 
7.4675500000000001, 7.4675500000000001, 7.4675500000000001, 
7.4675500000000001] 

至此一轮迭代(第一个颗树拟合)完成,下面开始第二轮迭代(第二颗树拟合)。


  • 强学习 f 1 ( x ) f_1(x) f1(x)
[7.1999666666666666, 7.1999666666666666, 7.1999666666666666, 
7.1999666666666666, 7.1999666666666666, 7.1999666666666666, 
7.4675500000000001, 7.4675500000000001, 7.4675500000000001, 
7.4675500000000001] 
  • 拟合第二颗树( m = 2 m=2 m=2 r i m = − [ ∂ L ( y i , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) = y i − f m − 1 ( x i ) = y i − f 1 ( x i ) 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) rim=[f(xi)L(yi,f(xi))]f(x)=fm1(x)=yifm1(xi)=yif1(xi)

  • 利用 ( x i , r i m ) , ( i = 1 , 2 , . . N ) (x_{i},r_{im}),(i=1,2,..N) (xi,rim),(i=1,2,..N),我们可以拟合一颗CART回归树。

x i x_i xi12345678910
r i 2 r_{i2} ri2-1.63996667-1.49996667-1.28996667-0.79996667-0.39996667-0.149966671.432451.232451.532451.58245
 [-1.639966666666667, -1.4999666666666664, -1.2899666666666665, 
 -0.79996666666666627, -0.3999666666666668, -0.1499666666666668, 
 1.4324500000000002, 1.2324499999999992, 1.5324499999999999, 
 1.5824500000000006] 
  • 决策树的构建
    选不同 x i x_i xi x 1 − x 9 x_1-x_9 x1x9)做为分裂点的结果如下:
1.4289876354595334, 1.2145779184027778, 0.94102838038548786, 
0.7759147700617286, 0.63424046777777798, 0.32765763888888905, 
0.9921468829365081, 1.2236044283854166, 1.451869445987654

可以得到当选择 6 作为分裂点时 M S E s u m MSE_{sum} MSEsum 最小
在这里插入图片描述

  • 得到了第 m m m 颗回归树,其对应的叶节点区域 R j m , j = 1 , 2 , . . . , J m R_{jm},j=1,2,...,J_{m} Rjm,j=1,2,...,Jm。其中 J m J_{m} Jm 为叶子节点的个数
    落地为:得到了第 2 2 2 颗回归树,其对应的叶节点区域 R j 2 , j = 1 , 2 R_{j2},j=1,2 Rj2,j=1,2
    R 12 R_{12} R12 x 1 − x 6 x_1-x_6 x1x6
    R 22 R_{22} R22 x 7 − x 10 x_7-x_{10} x7x10
    γ 12 = r 12 ˉ + r 22 ˉ + r 32 ˉ + r 42 ˉ + r 52 ˉ + r 62 ˉ 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=6r12ˉ+r22ˉ+r32ˉ+r42ˉ+r52ˉ+r62ˉ=0.9633
    γ 22 = r 72 ˉ + r 82 ˉ + r 92 ˉ 6 = 1.44495 \gamma_{22}=\frac{\bar{r_{72}}+\bar{r_{82}}+\bar{r_{92}}}{6} =1.44495 γ22=6r72ˉ+r82ˉ+r92ˉ=1.44495

  • 更新强学习器
    f m ( x ) = f m − 1 ( x ) + ∑ j = 1 J m γ j m I ( x ∈ R j m ) f_{m}(x)=f_{m-1}(x) + \sum_{j=1}^{J_{m}}\gamma _{jm}I(x\in R_{jm}) fm(x)=fm1(x)+j=1JmγjmI(xRjm)
    落地为,更新 f 2 ( x i ) f_2(x_i) f2(xi)
    f 2 ( x i ) = f 1 ( x i ) + ∑ j = 1 2 γ j 2 I ( x i ∈ R j 2 ) f_2(x_i) = f_1(x_i) + \sum_{j=1}^{2}\gamma_{j2}I(x_i\in R_{j2}) f2(xi)=f1(xi)+j=12γj2I(xiRj2)
    例如更新 x 1 x_1 x1 的预测值, x 1 x_1 x1 落在 R 12 R_{12} R12
    f 2 ( x 1 ) = f 1 ( x 1 ) + 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 f2(x1)=f1(x1)+0.1γ12=7.19996+0.1(0.9633)=7.10363

    所有样本的更新结果如下,也即是强学习 f 2 ( x ) f_2(x) f2(x)

[7.1036366666666666, 7.1036366666666666, 7.1036366666666666, 
7.1036366666666666, 7.1036366666666666, 7.1036366666666666, 
7.6120450000000002, 7.6120450000000002, 7.6120450000000002, 
7.6120450000000002] 

当只有两颗树的时候, f 2 ( x ) f_2(x) f2(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的计算过程

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')

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] 

【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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值