【尊重原创,转载请注明出处】http://blog.csdn.net/zpalyq110/article/details/79527653 
写在前面:  去年学习GBDT之初,为了加强对算法的理解,整理了一篇笔记形式的文章,发出去之后发现阅读量越来越多,渐渐也有了评论,评论中大多指出来了笔者理解或者编辑的错误,故重新编辑一版文章,内容更加翔实,并且在GitHub上实现了和本文一致的GBDT简易版(包括回归、二分类、多分类以及可视化),供大家交流探讨。感谢各位的点赞和评论,希望继续指出错误~ 
  Github:https://github.com/Freemanzxp/GBDT_Simple_Tutorial  
 简介:  GBDT 的全称是 Gradient Boosting Decision Tree,梯度提升树,在传统机器学习算法中,GBDT算的上TOP3的算法。想要理解GBDT的真正意义,那就必须理解GBDT中的Gradient Boosting 和Decision Tree分别是什么?
 1. Decision Tree:CART回归树  首先,GBDT使用的决策树是CART回归树,无论是处理回归问题还是二分类以及多分类,GBDT使用的决策树通通都是都是CART回归树。为什么不用CART分类树呢?因为GBDT每次迭代要拟合的是梯度值 ,是连续值所以要用回归树。 
  对于回归树算法来说最重要的是寻找最佳的划分点,那么回归树中的可划分点包含了所有特征的所有可取的值。在分类树中最佳划分点的判别标准是熵或者基尼系数,都是用纯度来衡量的,但是在回归树中的样本标签是连续数值,所以再使用熵之类的指标不再合适,取而代之的是平方误差,它能很好的评判拟合程度。
回归树生成算法:  
输入:训练数据集D D  D D  : 
输出:回归树f ( x ) f ( x )  f(x) f ( x )  . 
在训练数据集所在的输入空间中,递归的将每个区域划分为两个子区域并决定每个子区域上的输出值,构建二叉决策树: 
(1)选择最优切分变量j j  j j  与切分点s s  s s  ,求解m i n j , s [ m i n c 1 ∑ x i ∈ R 1 ( j , s ) ( y i − c 1 ) 2 + m i n c 2 ∑ x i ∈ R 2 ( j , s ) ( y i − c 2 ) 2   ] m i n j , s [ m i n c 1 ∑ x i ∈ R 1 ( j , s ) ( y i − c 1 ) 2 + m i n c 2 ∑ x i ∈ R 2 ( j , s ) ( y i − c 2 ) 2   ]  \underset{j,s}{min}\left [ \underset{c_1}{min}\underset{x_i\in R_1(j,s)}{\sum}(y_i-c_1)^2 + \underset{c_2}{min}\underset{x_i\in R_2(j,s)}{\sum}(y_i-c_2)^2 \right ] j , s m i n  ⎣ ⎡  c 1  m i n  x i  ∈ R 1  ( j , s ) ∑  ( y i  − c 1  ) 2 + c 2  m i n  x i  ∈ R 2  ( j , s ) ∑  ( y i  − c 2  ) 2   ⎦ ⎤   遍历变量j j  j j  ,对固定的切分变量j j  j j  扫描切分点s s  s s  ,选择使得上式达到最小值的对( j , s ) ( j , s )  (j,s) ( j , s )  . 
(2)用选定的对( j , s ) ( j , s )  (j,s) ( j , s )  划分区域并决定相应的输出值:R 1 ( j , s ) = x ∣ x ( j ) ≤ s , R 2 ( j , s ) = x ∣ x ( j ) > s R 1 ( j , s ) = x ∣ x ( j ) ≤ s , R 2 ( j , s ) = x ∣ x ( j ) > s  R_1(j,s)={x|x^{(j)}\leq s}, R_2(j,s)={x|x^{(j)}> s} R 1  ( j , s ) = x ∣ x ( j ) ≤ s , R 2  ( j , s ) = x ∣ x ( j ) > s c m ˆ = 1 N ∑ x 1 ∈ R m ( j , s ) y i , x ∈ R m , m = 1 , 2 c m ^ = 1 N ∑ x 1 ∈ R m ( j , s ) y i , x ∈ R m , m = 1 , 2  \hat{c_m} =\frac{1}{N}\underset{x_1\in R_m(j,s)}{\sum}y_i, x \in R_m, m=1,2 c m  ^  = N 1  x 1  ∈ R m  ( j , s ) ∑  y i  , x ∈ R m  , m = 1 , 2  (3)继续对两个子区域调用步骤(1)和(2),直至满足停止条件。 
(4)将输入空间划分为M M  M M  个区域 R 1 , R 2 , . . . R M R 1 , R 2 , . . . R M  R_1,R_2,...R_M R 1  , R 2  , . . . R M   ,生成决策树:f ( x ) = ∑ M m = 1 c ˆ m I ( x ∈ R m ) f ( x ) = ∑ m = 1 M c ^ m I ( x ∈ R m )  f(x)=\sum_{m=1}^{M}\hat{c}m I(x \in R_m)  f ( x ) = m = 1 ∑ M  c ^ m  I ( x ∈ R m  ) 
 2. Gradient Boosting: 拟合负梯度  梯度提升树(Grandient Boosting)是提升树(Boosting Tree)的一种改进算法,所以在讲梯度提升树之前先来说一下提升树。
  先来个通俗理解:假如有个人30岁,我们首先用20岁去拟合,发现损失有10岁,这时我们用6岁去拟合剩下的损失,发现差距还有4岁,第三轮我们用3岁拟合剩下的差距,差距就只有一岁了。如果我们的迭代轮数还没有完,可以继续迭代下面,每一轮迭代,拟合的岁数误差都会减小。最后将每次拟合的岁数加起来便是模型输出的结果。
提升树算法:  
(1)初始化f 0 ( x ) = 0 f 0 ( x ) = 0  f_0(x)=0 f 0  ( x ) = 0  
(2)对m = 1 , 2 , . . . , M m = 1 , 2 , . . . , M  m=1,2,...,M m = 1 , 2 , . . . , M  
 (a)计算残差r m i = y i − f m − 1 ( x ) , i = 1 , 2 , . . . , N r m i = y i − f m − 1 ( x ) , i = 1 , 2 , . . . , N  r{mi}=y_i-f_{m-1}(x), i=1,2,...,N r m i  = y i  − f m − 1  ( x ) , i = 1 , 2 , . . . , N   (b)拟合残差r m i r m i  r_{mi} r m i   学习一个回归树,得到h m ( x ) h m ( x )  h_m(x) h m  ( x )  
 (c)更新f m ( x ) = f m − 1 + h m ( x ) f m ( x ) = f m − 1 + h m ( x )  f_m(x) = f_{m-1}+h_m(x) f m  ( x ) = f m − 1  + h m  ( x )  
(3)得到回归问题提升树f M ( x ) = ∑ M m = 1 h m ( x ) f M ( x ) = ∑ m = 1 M h m ( x )  f_M(x)=\sum_{m=1}^Mh_m(x) f M  ( x ) = m = 1 ∑ M  h m  ( x ) 
上面伪代码中的残差 是什么? 
在提升树算法中,假设我们前一轮迭代得到的强学习器是f t − 1 ( x ) f t − 1 ( x )  f_{t−1}(x) f t − 1  ( x )  损失函数是L ( y , f t − 1 ( x ) ) L ( y , f t − 1 ( x ) )  L(y,f_{t−1}(x)) L ( y , f t − 1  ( x ) )  我们本轮迭代的目标是找到一个弱学习器h t ( x ) h t ( x )  h_t(x) h t  ( 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,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 , f t − 1 ( x ) + h t ( x ) ) L ( y , f t − 1 ( x ) + h t ( x ) )  L(y,f_{t−1}(x)+h_t(x)) L ( y , f t − 1  ( x ) + h t  ( x ) ) = ( y − f t − 1 ( x ) − h t ( x ) ) 2 = ( y − f t − 1 ( x ) − h t ( x ) ) 2  =(y-f_{t−1}(x)-h_t(x))^2 = ( y − f t − 1  ( x ) − h t  ( x ) ) 2 = ( r − h t ( x ) ) 2 = ( r − h t ( x ) ) 2  =(r-h_t(x))^2 = ( r − h t  ( x ) ) 2  这里,r = y − f t − 1 ( x ) r = y − f t − 1 ( x )  r=y-f_{t−1}(x) r = y − f t − 1  ( x )  是当前模型拟合数据的残差(residual)所以,对于提升树来说只需要简单地拟合当前模型的残差。 
  回到我们上面讲的那个通俗易懂的例子中,第一次迭代的残差是10岁,第二 次残差4岁……
  当损失函数是平方损失和指数损失函数时,梯度提升树每一步优化是很简单的,但是对于一般损失函数而言,往往每一步优化起来不那么容易,针对这一问题,Friedman提出了梯度提升树算法,这是利用最速下降的近似方法,其关键是利用损失函数的负梯度作为提升树算法中的残差的近似值。  
那么负梯度长什么样呢? 
第t轮的第i个样本的损失函数的负梯度为:Unexpected text node: '    ' Unexpected text node: '    ' − [ ∂ f ( x i  ) ∂ L ( y , f ( x i  ) ) )  ] f ( x ) = f t − 1  ( x )   此时不同的损失函数将会得到不同的负梯度,如果选择平方损失L ( y , f ( x i ) ) = 1 2 ( y − f ( x i ) ) 2 L ( y , f ( x i ) ) = 1 2 ( y − f ( x i ) ) 2  L(y,f(x_i)) = \frac{1}{2}(y-f(x_i))^2 L ( y , f ( x i  ) ) = 2 1  ( y − f ( x i  ) ) 2  负梯度为Unexpected text node: '    ' Unexpected text node: '    ' − [ ∂ f ( x i  ) ∂ L ( y , f ( x i  ) ) )  ] f ( x ) = f t − 1  ( x )  = y − f ( x i  )    此时我们发现GBDT的负梯度就是残差 ,所以说对于回归问题,我们要拟合的就是残差。 
  那么对于分类问题呢?二分类和多分类的损失函数都是l o g l o s s l o g l o s s  log loss l o g l o s s  ,本文以回归问题为例进行讲解 。
 3. GBDT算法原理  上面两节分别将Decision Tree和Gradient Boosting介绍完了,下面将这两部分组合在一起就是我们的GBDT了。
GBDT算法:  
(1)初始化弱学习器Unexpected text node: '  ' Unexpected text node: '  ' f 0  ( x ) = a r g m i n c  i = 1 ∑ N  L ( y i  , c )  (2)对m = 1 , 2 , . . . , M 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 i = 1 , 2 , . . . , N  ,计算负梯度,即残差r i m = − [ ∂ L ( y i , f ( x i ) ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) r i m = − [ ∂ L ( y i , f ( x i ) ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x )  r_{im} = -\bigg[\frac{\partial L(y_i, f(x_i)))}{\partial f(x_i)}\bigg]{f(x) = f {m-1} (x)} r i m  = − [ ∂ f ( x i  ) ∂ L ( y i  , f ( x i  ) ) )  ] f ( x ) = f m − 1  ( x )   
 (b)将上步得到的残差作为样本新的真实值,并将数据( x i , r i m ) , i = 1 , 2 , . . N ( x i , r i m ) , i = 1 , 2 , . . N  (x_i,r_{im}), i=1,2,..N ( x i  , r i m  ) , i = 1 , 2 , . . N  作为下棵树的训练数据,得到一颗新的回归树f m ( x ) f m ( x )  f_{m} (x) f m  ( x )  其对应的叶子节点区域为R j m , j = 1 , 2 , . . . , J R j m , j = 1 , 2 , . . . , J  R_{jm}, j =1,2,..., J R j m  , j = 1 , 2 , . . . , J  。其中J J  J J  为回归树t的叶子节点的个数。 
 (c)对叶子区域j = 1 , 2 , . . J j = 1 , 2 , . . J  j =1,2,..J j = 1 , 2 , . . J  计算最佳拟合值Unexpected text node: '  ' Unexpected text node: '  ' Υ j m  = Υ a r g m i n   x i  ∈ R j m  ∑  L ( y i  , f m − 1  ( x i  ) + Υ )   (d)更新强学习器f m ( x ) = f m − 1 ( x ) + ∑ J j = 1 Υ j m I ( x ∈ R j m ) f m ( x ) = f m − 1 ( x ) + ∑ j = 1 J Υ j m I ( x ∈ R j m )  f_{m}(x) = f_{m-1}(x) + \sum\limits_{j=1}^{J}\Upsilon_{jm}I(x \in R_{jm}) f m  ( x ) = f m − 1  ( x ) + j = 1 ∑ J  Υ j m  I ( x ∈ R j m  )  (3)得到最终学习器f ( x ) = f M ( x ) = f 0 ( x ) + ∑ M m = 1 ∑ J j = 1 Υ j m I ( x ∈ R j m ) f ( x ) = f M ( x ) = f 0 ( x ) + ∑ m = 1 M ∑ j = 1 J Υ j m I ( x ∈ R j m )  f(x) = f_M(x) =f_0(x) + \sum\limits_{m=1}^{M}\sum\limits_{j=1}^{J}\Upsilon_{jm}I(x \in R_{jm}) f ( x ) = f M  ( x ) = f 0  ( x ) + m = 1 ∑ M  j = 1 ∑ J  Υ j m  I ( x ∈ R j m  ) 
 4. 实例详解本人用python以及pandas库实现GBDT的简易版本,在下面的例子中用到的数据都在github可以找到,大家可以结合代码和下面的例子进行理解,欢迎star~  
  Github:https://github.com/Freemanzxp/GBDT_Simple_Tutorial  
数据介绍:   如下表所示:一组数据,特征为年龄、体重,身高为标签值。共有5条数据,前四条为训练样本,最后一条为要预测的样本。
编号 
年龄(岁) 
体重(kg) 
身高(m)(标签值) 
0 
5 
20 
1.1 
1 
7 
30 
1.3 
2 
21 
70 
1.7 
3 
30 
60 
1.8 
4(要预测的) 
25 
65 
? 
 
训练阶段:  
参数设置: 
学习率:learning_rate=0.1 
迭代次数:n_trees=5 
树的深度:max_depth=3 
1.初始化弱学习器: Unexpected text node: '  ' Unexpected text node: '  ' f 0  ( x ) = a r g m i n c  i = 1 ∑ N  L ( y i  , c )    损失函数为平方损失,因为平方损失函数是一个凸函数,直接求导,倒数等于零,得到c c       c c  。∑ N i = 1 ∂ L ( y i , c ) ) ∂ c = ∑ N i = 1 ∂ ( 1 2 ( y i − c ) 2 ) ∂ c = ∑ N i = 1 c − y i ∑ i = 1 N ∂ L ( y i , c ) ) ∂ c = ∑ i = 1 N ∂ ( 1 2 ( y i − c ) 2 ) ∂ c = ∑ i = 1 N c − y i       \sum\limits_{i=1}^{N}\frac{\partial L(y_i,c))}{\partial c}=\sum\limits_{i=1}^{N}\frac{\partial (\frac{1}{2}(y_i-c)^2)}{\partial c}=\sum\limits_{i=1}^{N}c-y_i i = 1 ∑ N  ∂ c ∂ L ( y i  , c ) )  = i = 1 ∑ N  ∂ c ∂ ( 2 1  ( y i  − c ) 2 )  = i = 1 ∑ N  c − y i   令导数等于0∑ N i = 1 c − y i = 0 ∑ i = 1 N c − y i = 0       \sum\limits_{i=1}^{N}c-y_i=0 i = 1 ∑ N  c − y i  = 0 c = ( ∑ N i = 1 y i ) / N c = ( ∑ i = 1 N y i ) / N       c=(\sum\limits_{i=1}^{N}y_i)/N  c = ( i = 1 ∑ N  y i  ) / N  所以初始化时,c c       c c  取值为所有训练样本标签值的均值。c = ( 1.1 + 1.3 + 1.7 + 1.8 ) / 4 = 1.475 c = ( 1.1 + 1.3 + 1.7 + 1.8 ) / 4 = 1.475       c=(1.1+1.3+1.7+1.8)/4=1.475 c = ( 1 . 1 + 1 . 3 + 1 . 7 + 1 . 8 ) / 4 = 1 . 4 7 5  ,此时得到初始学习器f 0 ( x ) f 0 ( x )       f_0(x) f 0  ( x ) f 0 ( x ) = c = 1.475 f 0 ( x ) = c = 1.475       f_0(x) = c=1.475 f 0  ( x ) = c = 1 . 4 7 5 
2.对迭代轮数m=1,2,…,M:  
  由于我们设置了迭代次数:n_trees=5,这里的M = 5 M = 5       M=5 M = 5  。 
  计算负梯度,根据上文损失函数为平方损失时,负梯度就是残差残差,再直白一点就是 y y       y y  与上一轮得到的学习器f m − 1 f m − 1       f_{m-1} f m − 1   的差值 
  r i 1 = − [ ∂ L ( y i , f ( x i ) ) ) ∂ f ( x i ) ] f ( x ) = f 0 ( x ) r i 1 = − [ ∂ L ( y i , f ( x i ) ) ) ∂ f ( x i ) ] f ( x ) = f 0 ( x )       r_{i1} = -\bigg[\frac{\partial L(y_i, f(x_i)))}{\partial f(x_i)}\bigg]_{f(x) = f_{0} (x)} r i 1  = − [ ∂ f ( x i  ) ∂ L ( y i  , f ( x i  ) ) )  ] f ( x ) = f 0  ( x )   
残差在下表列出:
编号 
真实值 
f 0 ( x ) f 0 ( x )       f_{0} (x) f 0  ( x )  
残差 
0 
1.1 
1.475 
-0.375 
1 
1.3 
1.475 
-0.175 
2 
1.7 
1.475 
0.225 
3 
1.8 
1.475 
0.325 
 
此时将残差作为样本的真实值来训练弱学习器f 1 ( x ) f 1 ( x )       f_{1} (x) f 1  ( x )  ,即下表数据
编号 
年龄(岁) 
体重(kg) 
标签值  
0 
5 
20 
-0.375 
1 
7 
30 
-0.175 
2 
21 
70 
0.225 
3 
30 
60 
0.325 
 
  接着,寻找回归树的最佳划分节点,遍历每个特征的每个可能取值。从年龄特征的5开始,到体重特征的70结束,分别计算分裂后两组数据的平方损失(Square Error),S E l S E l       SE_l S E l   左节点平方损失,S E r S E r       SE_r S E r   右节点平方损失,找到使平方损失和S E s u m = S E l + S E r S E s u m = S E l + S E r       SE_{sum}=SE_l+SE_r S E s u m  = S E l  + S E r   最小的那个划分节点,即为最佳划分节点。 
  例如:以年龄7为划分节点,将小于7的样本划分为到左节点,大于等于7的样本划分为右节点。左节点包括x 0 x 0       x_0 x 0   ,右节点包括样本x 1 , x 2 , x 3 x 1 , x 2 , x 3       x_1,x_2,x_3 x 1  , x 2  , x 3   ,S E l = 0 , S E r = 0.140 , S E s u m = 0.140 S E l = 0 , S E r = 0.140 , S E s u m = 0.140       SE_l = 0,SE_r=0.140,SE_{sum}=0.140 S E l  = 0 , S E r  = 0 . 1 4 0 , S E s u m  = 0 . 1 4 0  ,所有可能划分情况如下表所示:
划分点 
小于划分点的样本 
大于等于划分点的样本 
S E l S E l       SE_l S E l   
S E r S E r       SE_r S E r   
S E s u m S E s u m       SE_{sum} S E s u m   
年龄5 
/ 
0,1,2,3 
0 
0.327 
0.327  
年龄7 
0 
1,2,3 
0 
0.140 
0.140  
年龄21 
0,1 
2,3 
0.020 
0.005 
0.025  
年龄30 
0,1,2 
3 
0.187 
0 
0.187  
体重20 
/ 
0,1,2,3 
0 
0.327 
0.327  
体重30 
0 
1,2,3 
0 
0.140 
0.140  
体重60 
0,1 
2,3 
0.020 
0.005 
0.025  
体重70 
0,1,3 
2 
0.260 
0 
0.260  
 
  以上划分点是的总平方损失最小为0.025 有两个划分点:年龄21和体重60,所以随机选一个作为划分点,这里我们选 年龄21  
  现在我们的第一棵树长这个样子: 
  我们设置的参数中树的深度max_depth=3,现在树的深度只有2,需要再进行一次划分,这次划分要对左右两个节点分别进行划分:
  对于左节点 ,只含有0,1两个样本,根据下表我们选择年龄7 划分
划分点 
小于划分点的样本 
大于等于划分点的样本 
S E l S E l       SE_l S E l   
S E r S E r       SE_r S E r   
S E s u m S E s u m       SE_{sum} S E s u m   
年龄5 
/ 
0,1 
0 
0.020 
0.020  
年龄7 
0 
1 
0 
0 
0  
体重20 
/ 
0,1 
0 
0.020 
0.020  
体重30 
0 
1 
0 
0 
0  
 
  对于右节点 ,只含有2,3两个样本,根据下表我们选择年龄30 划分(也可以选体重70 )
划分点 
小于划分点的样本 
大于等于划分点的样本 
S E l S E l       SE_l S E l   
S E r S E r       SE_r S E r   
S E s u m S E s u m       SE_{sum} S E s u m   
年龄21 
/ 
2,3 
0 
0.005 
0.005  
年龄30 
2 
3 
0 
0 
0  
体重60 
/ 
2,3 
0 
0.005 
0.005  
体重70 
3 
2 
0 
0 
0  
 
  现在我们的第一棵树长这个样子: 
  此时我们的树深度满足了设置,还需要做一件事情,给这每个叶子节点分别赋一个参数Υ Υ       \Upsilon Υ  ,来拟合残差。Unexpected text node: '  ' Unexpected text node: '  ' Υ j 1  = Υ a r g m i n   x i  ∈ R j 1  ∑  L ( y i  , f 0  ( x i  ) + Υ )    这里其实和上面初始化学习器是一个道理,平方损失,求导,令导数等于零,化简之后得到每个叶子节点的参数Υ Υ       \Upsilon Υ  ,其实就是标签值的均值。这个地方的标签值不是原始的 y y       y y  ,而是本轮要拟合的标残差 y − f 0 ( x ) y − f 0 ( x )       y-f_0(x) y − f 0  ( x )  . 
  根据上述划分结果,为了方便表示,规定从左到右为第1 , 2 , 3 , 4 1 , 2 , 3 , 4       1,2,3,4 1 , 2 , 3 , 4  个叶子结点( x 0 ∈ R 11 ) , Υ 11 = − 0.375 ( x 0 ∈ R 11 ) , Υ 11 = − 0.375       (x_0 \in R_{11}),\Upsilon_{11}=-0.375 ( x 0  ∈ R 1 1  ) , Υ 1 1  = − 0 . 3 7 5 ( x 1 ∈ R 21 ) , Υ 21 = − 0.175 ( x 1 ∈ R 21 ) , Υ 21 = − 0.175       (x_1 \in R_{21}),\Upsilon_{21}=-0.175 ( x 1  ∈ R 2 1  ) , Υ 2 1  = − 0 . 1 7 5 ( x 2 ∈ R 31 ) , Υ 31 = 0.225 ( x 2 ∈ R 31 ) , Υ 31 = 0.225       (x_2 \in R_{31}),\Upsilon_{31}=0.225 ( x 2  ∈ R 3 1  ) , Υ 3 1  = 0 . 2 2 5 ( x 3 ∈ R 41 ) , Υ 41 = 0.325 ( x 3 ∈ R 41 ) , Υ 41 = 0.325       (x_3 \in R_{41}),\Upsilon_{41}=0.325 ( x 3  ∈ R 4 1  ) , Υ 4 1  = 0 . 3 2 5  
  此时的树长这个样子:
  此时可更新强学习器,需要用到参数学习率:learning_rate=0.1,用l r l r       lr l r  表示。f 1 ( x ) = f 0 ( x ) + l r ∗ ∑ 4 j = 1 Υ j 1 I ( x ∈ R j 1 ) f 1 ( x ) = f 0 ( x ) + l r ∗ ∑ j = 1 4 Υ j 1 I ( x ∈ R j 1 )       f_{1}(x) = f_{0}(x) + lr *\sum\limits_{j=1}^{4}\Upsilon_{j1}I(x \in R_{j1}) f 1  ( x ) = f 0  ( x ) + l r ∗ j = 1 ∑ 4  Υ j 1  I ( x ∈ R j 1  )  
为什么要用学习率呢?这是Shrinkage 的思想,如果每次都全部加上(学习率为1)很容易一步学到位导致过拟合。
重复此步骤,直到 m > 5 m > 5       m>5 m > 5   结束,最后生成5棵树。 下面将展示每棵树最终的结构,这些图都是GitHub上的代码生成的,感兴趣的同学可以去一探究竟 Github:https://github.com/Freemanzxp/GBDT_Simple_Tutorial 第一棵树: 第二棵树: 第三棵树: 第四棵树: 第五棵树: 
4.得到最后的强学习器: f ( x ) = f 5 ( x ) = f 0 ( x ) + ∑ 5 m = 1 ∑ 4 j = 1 Υ j m I ( x ∈ R j m ) f ( x ) = f 5 ( x ) = f 0 ( x ) + ∑ m = 1 5 ∑ j = 1 4 Υ j m I ( x ∈ R j m )       f(x) = f_{5}(x) =f_0(x) + \sum\limits_{m=1}^{5}\sum\limits_{j=1}^{4}\Upsilon_{jm}I(x \in R_{jm}) f ( x ) = f 5  ( x ) = f 0  ( x ) + m = 1 ∑ 5  j = 1 ∑ 4  Υ j m  I ( x ∈ R j m  ) 
5.预测样本5:  
  f 0 ( x ) = 1.475 f 0 ( x ) = 1.475       f_0(x)=1.475 f 0  ( x ) = 1 . 4 7 5  
  在f 1 ( x ) f 1 ( x )       f_1(x) f 1  ( x )  中,样本4的年龄为25,大于划分节点21岁,又小于30岁,所以被预测为0.2250 。 
  在f 2 ( x ) f 2 ( x )       f_2(x) f 2  ( x )  中,样本4的…此处省略…所以被预测为0.2025  
   为什么是0.2025?这是根据第二颗树得到的,可以GitHub简单运行一下代码  
  在f 3 ( x ) f 3 ( x )       f_3(x) f 3  ( x )  中,样本4的…此处省略…所以被预测为0.1823  
  在f 4 ( x ) f 4 ( x )       f_4(x) f 4  ( x )  中,样本4的…此处省略…所以被预测为0.1640  
  在f 5 ( x ) f 5 ( x )       f_5(x) f 5  ( x )  中,样本4的…此处省略…所以被预测为0.1476 最终预测结果: f ( x ) = 1.475 + 0.1 ∗ ( 0.225 + 0.2025 + 0.1823 + 0.164 + 0.1476 ) = 1.56714 f ( x ) = 1.475 + 0.1 ∗ ( 0.225 + 0.2025 + 0.1823 + 0.164 + 0.1476 ) = 1.56714       f(x) =1.475+ 0.1 * (0.225+0.2025+0.1823+0.164+0.1476) = 1.56714 f ( x ) = 1 . 4 7 5 + 0 . 1 ∗ ( 0 . 2 2 5 + 0 . 2 0 2 5 + 0 . 1 8 2 3 + 0 . 1 6 4 + 0 . 1 4 7 6 ) = 1 . 5 6 7 1 4 
 4. 总结 
本文章从GBDT算法的原理到实例详解进行了详细描述,但是目前只写了回归问题,GitHub上的代码也是实现了回归、二分类、多分类以及树的可视化,希望大家继续批评指正,感谢各位的关注。
 参考资料 
李航 《统计学习方法》 
Friedman J H . Greedy Function Approximation: A Gradient Boosting Machine[J]. The Annals of Statistics, 2001, 29(5):1189-1232. 
【尊重原创,转载请注明出处】 http://blog.csdn.net/zpalyq110/article/details/79527653 
                                </div>