深入理解GBDT二分类算法

目录:

  1. GBDT分类算法简介
  2. GBDT二分类算法
    2.1 逻辑回归的对数损失函数
    2.2 GBDT二分类原理
  3. GBDT二分类算法实例
  4. 手撕GBDT二分类算法
    4.1 用Python3实现GBDT二分类算法
    4.2 用sklearn实现GBDT二分类算法
  5. GBDT分类任务常见的损失函数
  6. 总结
  7. Reference

本文的主要内容概览:
在这里插入图片描述

1. GBDT分类算法简介

GBDT无论用于分类还是回归,一直使用的是CART回归树。GBDT不会因为我们所选择的任务是分类任务就选用分类树,这里的核心原因是GBDT每轮的训练是在上一轮训练模型的负梯度值基础之上训练的。这就要求每轮迭代的时候,真实标签减去弱分类器的输出结果是有意义的,即残差是有意义的。如果选用的弱分类器是分类树,类别相减是没有意义的。对于这样的问题,可以采用两种方法来解决:

  • 采用指数损失函数,这样GBDT就退化成了Adaboost,能够解决分类的问题;
  • 使用类似于逻辑回归的对数似然损失函数,如此可以通过结果的概率值与真实概率值的差距当做残差来拟合;

下面我们就通过二分类问题,去看看GBDT究竟是如何做分类的。

2. GBDT二分类算法

2.1 逻辑回归的对数损失函数

逻辑回归的预测函数为:
h θ ( x ) = 1 1 + e − θ T x h_{\theta}(x) = \frac{1}{1+ e^{-\theta^{T} x}} hθ(x)=1+eθTx1
函数 h θ ( x ) h_{\theta}(x) hθ(x) 的值有特殊的含义,它表示结果取 1 1 1 的概率,因此对于输入 x x x 分类结果为类别 1 1 1 和类别 0 0 0 的概率分别为:
P ( Y = 1 ∣ x ; θ ) = h θ ( x ) P(Y=1|x;\theta) = h_{\theta}(x) P(Y=1x;θ)=hθ(x)
P ( Y = 0 ∣ x ; θ ) = 1 − h θ ( x ) P(Y=0|x;\theta) =1 - h_{\theta}(x) P(Y=0x;θ)=1hθ(x)
下面我们根据上式,推导出逻辑回归的对数损失函数 L ( θ ) L(\theta) L(θ) 。上式综合起来可以写成:
P ( Y = y ∣ x ; θ ) = ( h θ ( x ) ) y ( 1 − h θ ( x ) ) 1 − y P(Y=y|x;\theta) = (h_{\theta}(x))^{y}(1-h_{\theta}(x))^{1-y} P(Y=yx;θ)=(hθ(x))y(1hθ(x))1y
然后取似然函数为:
l ( θ ) = ∏ i = 1 N P ( Y = y i ∣ x i ; θ ) = ∏ i = 1 N ( h θ ( x i ) ) y i ( 1 − h θ ( x i ) ) 1 − y i l(\theta) = \prod_{i=1}^{N}P(Y=y_{i}|x_{i};\theta)=\prod_{i=1}^{N}(h_{\theta}(x_{i}))^{y_{i}}(1-h_{\theta}(x_{i}))^{1- y_{i}} l(θ)=i=1NP(Y=yixi;θ)=i=1N(hθ(xi))yi(1hθ(xi))1yi
因为 l ( θ ) l(\theta) l(θ) l o g l ( θ ) logl(\theta) logl(θ) 在同一 θ \theta θ 处取得极值,因此我们接着取对数似然函数为:
L ( θ ) = ∑ i = 1 N [ y i l o g h θ ( x i ) + ( 1 − y i ) l o g ( 1 − h θ ( x i ) ) ] L(\theta) = \sum_{i=1}^{N}\left[ {y_{i}logh_{\theta}(x_{i})} + (1-y_{i})log(1-h_{\theta}(x_{i})) \right] L(θ)=i=1N[yiloghθ(xi)+(1yi)log(1hθ(xi))]
最大似然估计就是求使 L ( θ ) L(\theta) L(θ) 取最大值时的 θ \theta θ 。这里对 L ( θ ) L(\theta) L(θ) 取相反数,可以使用梯度下降法求解,求得的 θ \theta θ 就是要求的最佳参数:
J ( θ ) = − 1 N L ( θ ) = − 1 N ∑ i = 1 N [ y i l o g h θ ( x i ) + ( 1 − y i ) l o g ( 1 − h θ ( x i ) ) ] J(\theta) = - \frac{1}{N}L(\theta) =- \frac{1}{N} \sum_{i=1}^{N}\left[ {y_{i}logh_{\theta}(x_{i})} + (1-y_{i})log(1-h_{\theta}(x_{i})) \right] J(θ)=N1L(θ)=N1i=1N[yiloghθ(xi)+(1yi)log(1hθ(xi))]

2.2 GBDT二分类原理

逻辑回归单个样本 ( x i , y i ) (x_{i},y_{i}) (xi,yi) 的损失函数可以表达为:
L ( θ ) = − y i log ⁡ y i ^ − ( 1 − y i ) log ⁡ ( 1 − y i ^ ) L(\theta) = -y_i \log \hat{y_i} - (1-y_i) \log(1-\hat{y_i}) L(θ)=yilogyi^(1yi)log(1yi^)
其中, y i ^ = h θ ( x ) \hat{y_{i}} = h_{\theta}(x) yi^=hθ(x) 是逻辑回归预测的结果。假设GBDT第 M M M 步迭代之后当前学习器为 F ( x ) = ∑ m = 0 M h m ( x ) F(x) = \sum_{m=0}^M h_m(x) F(x)=m=0Mhm(x) ,将 y i ^ \hat{y_i} yi^ 替换为 F ( x ) F(x) F(x)带入上式之后,可将损失函数写为:
L ( y i , F ( x i ) ) = y i log ⁡ ( 1 + e − F ( x i ) ) + ( 1 − y i ) [ F ( x i ) + log ⁡ ( 1 + e − F ( x i ) ) ] L(y_{i},F(x_{i})) = y_i \log \left( 1+e^{-F(x_i)} \right) + (1-y_i) \left[ F(x_i) + \log \left( 1+e^{-F(x_i)} \right) \right]\\ L(yi,F(xi))=yilog(1+eF(xi))+(1yi)[F(xi)+log(1+eF(xi))]
其中,第 m m m 棵树对应的响应值为(损失函数的负梯度,即伪残差):
r m , i = − ∣ ∂ L ( y i , F ( x i ) ) ∂ F ( x i ) ∣ F ( x ) = F m − 1 ( x ) = y i − 1 1 + e − F ( x i ) = y i − y i ^ r_{m,i} = - \left|\frac{\partial L(y_{i},F(x_{i}))}{\partial F(x_{i})} \right|_{F(x)=F_{m-1}(x)} = y_i - \frac{1}{1+e^{-F(x_i)}}= y_i - \hat{y_i} rm,i=F(xi)L(yi,F(xi))F(x)=Fm1(x)=yi1+eF(xi)1=yiyi^
对于生成的决策树,计算各个叶子节点的最佳残差拟合值为:
c m , j = arg ⁡ min ⁡ c ∑ x i ∈ R m , j L ( y i , F m − 1 ( x i ) + c ) c_{m,j}=\underset{c}{ \arg \min } \sum_{x_{i} \in R_{m,j}} L(y_{i},F_{m-1}(x_{i})+c) cm,j=cargminxiRm,jL(yi,Fm1(xi)+c)
由于上式没有闭式解(closed form solution),我们一般使用近似值代替:
c m , j = ∑ x i ∈ R m , j r m , i ∑ x i ∈ R m , j ( y i − r m , i ) ( 1 − y i + r m , i ) c_{m,j} = \frac{\sum_{x_{i} \in R_{m,j}}^{}{r_{m,i}}}{\sum_{x_{i} \in R_{m,j}}^{}{(y_{i}-r_{m,i})(1-y_{i}+ r_{m,i}) }} cm,j=xiRm,j(yirm,i)(1yi+rm,i)xiRm,jrm,i

补充近似值代替过程:
假设仅有一个样本:
L ( y i , F ( x ) ) = − ( y i l n 1 1 + e − F ( x ) + ( 1 − y i ) l n ( 1 − 1 1 + e − F ( x ) ) ) L(y_{i},F(x)) = -(y_{i}ln\frac{1}{1+e^{-F(x)}}+(1-y_{i})ln(1-\frac{1}{1+e^{-F(x)}})) L(yi,F(x))=(yiln1+eF(x)1+(1yi)ln(11+eF(x)1))
P i = 1 1 + e − F ( x ) P_{i} = \frac{1}{1+e^{-F(x)}} Pi=1+eF(x)1 ,则 ∂ P i ∂ F ( x ) = P i ( 1 − P i ) \frac{\partial P_{i}}{\partial F(x)} = P_{i}(1-P_{i}) F(x)Pi=Pi(1Pi)
求一阶导:
∂ L ( y i , F ( x ) ) ∂ F ( x ) = ∂ L ( y i , F ( x ) ) ∂ P i ⋅ ∂ P i ∂ F ( x ) = − ( y i P i − 1 − y i 1 − P i ) ⋅ ( P i ⋅ ( 1 − P i ) ) = P i − y i \begin{aligned} \frac{\partial L(y_{i},F(x))}{\partial F(x)} &= \frac{\partial L(y_{i},F(x))}{\partial P_{i}} \cdot \frac{\partial P_{i}}{\partial F(x)} \\ &= -(\frac{y_{i}}{P_{i}} - \frac{1-y_{i}}{1-P_{i}}) \cdot (P_{i}\cdot(1-P_{i})) \\ & = P_{i} - y_{i} \end{aligned} F(x)L(yi,F(x))=PiL(yi,F(x))F(x)Pi=(Piyi1Pi1yi)(Pi(1Pi))=Piyi
求二阶导:
∂ 2 L ( y i , F ( x ) ) ∂ F ( x ) 2 = ( P i − y i ) ′ = P i ( 1 − P i ) \begin{aligned} \frac{\partial ^{2}L(y_{i},F(x))}{\partial F(x)^{2}} & = (P_{i} - y_{i})^{'}\\ & = P_{i}(1-P_{i}) \end{aligned} F(x)22L(yi,F(x))=(Piyi)=Pi(1Pi)
对于 L ( y i , F ( x ) + c ) L(y_{i},F(x)+c) L(yi,F(x)+c) 的泰勒二阶展开式:
L ( y i , F ( x ) + c ) = L ( y i , F ( x ) ) + ∂ L ( y i , F ( x ) ) ∂ F ( x ) ⋅ c + 1 2 ∂ 2 L ( y i , F ( x ) ) ∂ F ( x ) 2 c 2 L(y_{i},F(x)+c) = L(y_{i},F(x)) + \frac{\partial L(y_{i},F(x))}{\partial F(x)}\cdot c + \frac{1}{2} \frac{\partial ^{2}L(y_{i},F(x))}{\partial F(x)^{2}} c^{2} L(yi,F(x)+c)=L(yi,F(x))+F(x)L(yi,F(x))c+21F(x)22L(yi,F(x))c2
L ( y i , F ( x ) + c ) L(y_{i},F(x)+c) L(yi,F(x)+c) 取极值时,上述二阶表达式中的 c c c为:
c = − b 2 a = − ∂ L ( y i , F ( x ) ) ∂ F ( x ) 2 ( 1 2 ∂ 2 L ( y i , F ( x ) ) ∂ F ( x ) 2 ) = − ∂ L ( y i , F ( x ) ) ∂ F ( x ) ∂ 2 L ( y i , F ( x ) ) ∂ F ( x ) 2 ) ⇒ 一 阶 、 二 阶 导 代 入 y i − P i P i ( 1 − P i ) ⇒ r i = y i − P i r i ( y i − r i ) ( 1 − y i + r i ) \begin{aligned} c &= - \frac{b}{2a} = - \frac{\frac{\partial L(y_{i},F(x))}{\partial F(x)}}{2( \frac{1}{2} \frac{\partial ^{2}L(y_{i},F(x))}{\partial F(x)^{2}})} \\ &= - \frac{\frac{\partial L(y_{i},F(x))}{\partial F(x)}}{ \frac{\partial ^{2}L(y_{i},F(x))}{\partial F(x)^{2}})} \overset{一阶、二阶导代入}{\Rightarrow} \frac{y_{i} - P_{i}}{P_{i}(1-P_{i})} \\ & \overset{r_{i} = y_{i} - P_{i}}{\Rightarrow} \frac{r_{i}}{(y_{i}-r_{i})(1-y_{i}+ r_{i})} \end{aligned} c=2ab=2(21F(x)22L(yi,F(x)))F(x)L(yi,F(x))=F(x)22L(yi,F(x)))F(x)L(yi,F(x))Pi(1Pi)yiPiri=yiPi(yiri)(1yi+ri)ri

GBDT二分类算法完整的算法过程如下:

(1)初始化第一个弱学习器 F 0 ( x ) F_{0}(x) F0(x)

F 0 ( x ) = l o g P ( Y = 1 ∣ x ) 1 − P ( Y = 1 ∣ x ) F_{0}(x)=log\frac{P(Y=1|x)}{1-P(Y=1|x)} F0(x)=log1P(Y=1x)P(Y=1x)
其中, P ( Y = 1 ∣ x ) P(Y=1|x) P(Y=1x) 是训练样本中 y = 1 y=1 y=1 的比例,利用先验信息来初始化学习器。

(2)对于建立 M M 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 ,计算第 m m m 棵树对应的响应值(损失函数的负梯度,即伪残差):
r m , i = − [ ∂ L ( y i , F ( x i ) ) ∂ F ( x ) ] F ( x ) = F m − 1 ( x ) = y i − 1 1 + e − F ( x i ) r_{m,i} = - \left[ \frac{\partial L(y_{i},F(x_{i}))}{\partial F(x)} \right]_{F(x)=F_{m-1}(x) } = y_i - \frac{1}{1+e^{-F(x_i)}} rm,i=[F(x)L(yi,F(xi))]F(x)=Fm1(x)=yi1+eF(xi)1
b) 对于 i = 1 , 2 , … , N i = 1,2 , \dots , N i=1,2,,N ,利用CART回归树拟合数据 ( x i , r m , i ) \left(x_{i}, r_{m, i}\right) (xi,rm,i) ,得到第 m m m 棵回归树,其对应的叶子节点区域为 R m , j R_{m, j} Rm,j ,其中 j = 1 , 2 , … , J m j=1,2, \dots, J_{m} j=1,2,,Jm ,且 J m J_{m} Jm 为第 m m m棵回归树叶子节点的个数。

c) 对于 J m J_{m} Jm 个叶子节点区域 j = 1 , 2 , … , J m j=1,2, \dots, J_{m} j=1,2,,Jm,计算出最佳拟合值:
c m , j = ∑ x i ∈ R m , j r m , i ∑ x i ∈ R m , j ( y i − r m , i ) ( 1 − y i + r m , i ) c_{m,j} = \frac{\sum_{x_{i} \in R_{m,j}}^{}{r_{m,i}}}{\sum_{x_{i} \in R_{m,j}}^{}{(y_{i}-r_{m,i})(1-y_{i}+ r_{m,i}) }} cm,j=xiRm,j(yirm,i)(1yi+rm,i)xiRm,jrm,i

d) 更新强学习器 F m ( x ) F_{m}(x) Fm(x)
F m ( x ) = F m − 1 ( x ) + ∑ j = 1 J m c m , j I ( x ∈ R m , j ) F_{m}(x)=F_{m-1}(x)+\sum_{j=1}^{J_{m}} c_{m, j} I\left(x \in R_{m,j}\right) Fm(x)=Fm1(x)+j=1Jmcm,jI(xRm,j)

(3)得到最终的强学习器 F M ( x ) F_{M}(x) FM(x) 的表达式:

F M ( x ) = F 0 ( x ) + ∑ m = 1 M ∑ j = 1 J m c m , j I ( x ∈ R m , j ) F_{M}(x)=F_{0}(x)+\sum_{m=1}^{M} \sum_{j=1}^{J_{m}} c_{m,j} I\left(x \in R_{m, j}\right) FM(x)=F0(x)+m=1Mj=1Jmcm,jI(xRm,j)

从以上过程中可知,除了由损失函数引起的负梯度计算和叶子节点的最佳残差拟合值的计算不同,二元GBDT分类和GBDT回归算法过程基本相似。那么二元GBDT是如何做分类呢?

将逻辑回归的公式进行整理,我们可以得到 log ⁡ p 1 − p = θ T x \log \frac{p}{1-p} = \theta^{T}x log1pp=θTx ,其中 p = P ( Y = 1 ∣ x ) p=P(Y=1|x) p=P(Y=1x),也就是将给定输入 x x x 预测为正样本的概率。逻辑回归用一个线性模型去拟合 Y = 1 ∣ x Y=1|x Y=1x 这个事件的对数几率(odds) log ⁡ p 1 − p \log \frac{p}{1-p} log1pp。二元GBDT分类算法和逻辑回归思想一样,用一系列的梯度提升树去拟合这个对数几率,其分类模型可以表达为:
P ( Y = 1 ∣ x ) = 1 1 + e − F M ( x ) P(Y=1|x) = \frac{1}{1+e^{-F_{M}(x)}} P(Y=1x)=1+eFM(x)1

3. GBDT二分类算法实例

(1)数据集介绍

训练集如下表所示,一组数据的特征有年龄和体重,把身高大于1.5米作为分类边界,身高大于1.5米的令标签为1,身高小于等于1.5米的令标签为0,共有4组数据。
在这里插入图片描述

测试数据如下表所示,只有一组数据,年龄为25、体重为65,我们用在训练集上训练好的GBDT模型预测该组数据的身高是否大于1.5米?
在这里插入图片描述

(2)模型训练阶段

参数设置:

  • 学习率:learning_rate = 0.1
  • 迭代次数:n_trees = 5
  • 树的深度:max_depth = 3

1)初始化弱学习器:

F 0 ( x ) = l o g P ( Y = 1 ∣ x ) 1 − P ( Y = 1 ∣ x ) = l o g 2 2 = 0 F_{0}(x)=log\frac{P(Y=1|x)}{1-P(Y=1|x)}=log \frac{2}{2} = 0 F0(x)=log1P(Y=1x)P(Y=1x)=log22=0

2)对于建立 M M M棵分类回归树 m = 1 , 2 , … , M m = 1,2 , \dots , M m=1,2,,M

由于我们设置了迭代次数:n_trees=5,这就是设置了 M = 5 M=5 M=5

首先计算负梯度,根据上文损失函数为对数损失时,负梯度(即伪残差、近似残差)为:
r m , i = − [ ∂ L ( y i , F ( x i ) ) ∂ F ( x ) ] F ( x ) = F m − 1 ( x ) = y i − 1 1 + e − F ( x i ) r_{m,i} = - \left[ \frac{\partial L(y_{i},F(x_{i}))}{\partial F(x)} \right]_{F(x)=F_{m-1}(x) } = y_i - \frac{1}{1+e^{-F(x_i)}} rm,i=[F(x)L(yi,F(xi))]F(x)=Fm1(x)=yi1+eF(xi)1
我们知道梯度提升类算法,其关键是利用损失函数的负梯度的值作为回归问题提升树算法中的残差的近似值,拟合一个回归树。这里,为了称呼方便,我们把负梯度叫做残差。

现将残差的计算结果列表如下:
在这里插入图片描述

此时将残差作为样本的标签来训练弱学习器 F 1 ( x ) F_{1}(x) F1(x) ,即下表数据:
在这里插入图片描述

接着寻找回归树的最佳划分节点,遍历每个特征的每个可能取值。从年龄特征值为 5 5 5开始,到体重特征为 70 70 70结束,分别计算分裂后两组数据的平方损失(Square Error), S E l SE_{l} SEl 为左节点的平方损失, S E r SE_{r} SEr 为右节点的平方损失,找到使平方损失和 S E s u m = S E l + S E r SE_{sum} = SE_{l}+SE_{r} SEsum=SEl+SEr 最小的那个划分节点,即为最佳划分节点。

例如:以年龄 7 7 7为划分节点,将小于 7 7 7的样本划分为到左节点,大于等于 7 7 7的样本划分为右节点。左节点包括 x 0 x_{0} x0,右节点包括样本 x 1 , x 2 , x 3 x_{1},x_{2},x_{3} x1,x2,x3 S E l = 0 SE_{l}=0 SEl=0 S E r = 0.667 SE_{r}=0.667 SEr=0.667 S E s u m = 0.667 SE_{sum}=0.667 SEsum=0.667 ,所有可能的划分情况如下表所示:
在这里插入图片描述
以上划分点的总平方损失最小为 0.000 0.000 0.000,有两个划分点:年龄 21 21 21和体重 60 60 60,所以随机选一个作为划分点,这里我们选年龄 21 21 21。现在我们的第一棵树长这个样子:
在这里插入图片描述
我们设置的参数中树的深度max_depth=3,现在树的深度只有 2 2 2,需要再进行一次划分,这次划分要对左右两个节点分别进行划分,但是我们在生成树的时候,设置了三个树继续生长的条件:

  • 深度没有到达最大。树的深度设置为3,意思是需要生长成3层;
  • 点样本数 >= min_samples_split;
  • 此节点上的样本的标签值不一样。如果值一样说明已经划分得很好了,不需要再分;(本程序满足这个条件,因此树只有2层)

最终我们的第一棵回归树长下面这个样子:
在这里插入图片描述

此时我们的树满足了设置,还需要做一件事情,给这棵树的每个叶子节点分别赋一个参数 c c c,来拟合残差。
c 1 , j = ∑ x i ∈ R 1 , j r 1 , i ∑ x i ∈ R 1 , j ( y i − r 1 , i ) ( 1 − y i + r 1 , i ) c_{1,j} = \frac{\sum_{x_{i} \in R_{1,j}}^{}{r_{1,i}}}{\sum_{x_{i} \in R_{1,j}}^{}{(y_{i}-r_{1,i})(1-y_{i}+ r_{1,i}) }} c1,j=xiR1,j(yir1,i)(1yi+r1,i)xiR1,jr1,i
根据上述划分结果,为了方便表示,规定从左到右为第 1 , 2 1,2 1,2个叶子结点,其计算值过程如下:
( x 0 , x 1 ∈ R 1 , 1 ) , c 1 , 1 = − 2.0 (x_{0},x_{1}\in R_{1,1}), \qquad c_{1,1}=-2.0 (x0,x1R1,1),c1,1=2.0
( x 2 , x 3 ∈ R 1 , 2 ) , c 1 , 2 = 2.0 (x_{2}, x_{3}\in R_{1,2}), \qquad c_{1,2}=2.0 (x2,x3R1,2),c1,2=2.0
此时的第一棵树长下面这个样子:
在这里插入图片描述

接着更新强学习器,需要用到学习率:learning_rate=0.1,用lr表示。更新公式为:
F 1 ( x ) = F 0 ( x ) + l r ∗ ∑ j = 1 2 c 1 , j I ( x ∈ R 1 , j ) F_{1}(x)=F_{0}(x)+lr * \sum_{j=1}^{2} c_{1, j} I\left(x \in R_{1,j}\right) F1(x)=F0(x)+lrj=12c1,jI(xR1,j)

为什么要用学习率呢?这是Shrinkage的思想,如果每次都全部加上拟合值 c c c ,即学习率为 1 1 1,很容易一步学到位导致GBDT过拟合。

重复此步骤,直到 m > 5 m>5 m>5 结束,最后生成 5 5 5棵树。

下面将展示每棵树最终的结构,这些图都是我GitHub上的代码生成的,感兴趣的同学可以去运行一下代码。https://github.com/Microstrong0305/WeChat-zhihu-csdnblog-code/tree/master/Ensemble%20Learning/GBDT_GradientBoostingBinaryClassifier

第一棵树:
在这里插入图片描述
第二棵树:
在这里插入图片描述
第三棵树:
在这里插入图片描述
第四棵树:
在这里插入图片描述
第五棵树:
在这里插入图片描述

3)得到最后的强学习器:

F 5 ( x ) = F 0 ( x ) + ∑ m = 1 5 ∑ j = 1 2 c m , j I ( x ∈ R m , j ) F_{5}(x)=F_{0}(x)+\sum_{m=1}^{5} \sum_{j=1}^{2} c_{m,j} I\left(x \in R_{m, j}\right) F5(x)=F0(x)+m=15j=12cm,jI(xRm,j)

(3)模型预测阶段

  • F 0 ( x ) = 0 F_{0}(x) = 0 F0(x)=0
  • F 1 ( x ) F_{1}(x) F1(x) 中,测试样本的年龄为 25 25 25,大于划分节点 21 21 21岁,所以被预测为 2.0000 2.0000 2.0000
  • F 2 ( x ) F_{2}(x) F2(x) 中,测试样本的年龄为 25 25 25,大于划分节点 21 21 21岁,所以被预测为 1.8187 1.8187 1.8187
  • F 3 ( x ) F_{3}(x) F3(x) 中,测试样本的年龄为 25 25 25,大于划分节点 21 21 21岁,所以被预测为 1.6826 1.6826 1.6826
  • F 4 ( x ) F_{4}(x) F4(x) 中,测试样本的年龄为 25 25 25,大于划分节点 21 21 21岁,所以被预测为 1.5769 1.5769 1.5769
  • F 5 ( x ) F_{5}(x) F5(x) 中,测试样本的年龄为 25 25 25,大于划分节点 21 21 21岁,所以被预测为 1.4927 1.4927 1.4927

最终预测结果为:
F ( x ) = 0.0000 + 0.1 ∗ ( 2.0000 + 1.8187 + 1.6826 + 1.5769 + 1.4927 ) = 0.8571 F(x) = 0.0000 + 0.1 * (2.0000+1.8187+1.6826+1.5769+1.4927)=0.8571 F(x)=0.0000+0.1(2.0000+1.8187+1.6826+1.5769+1.4927)=0.8571
P ( Y = 1 ∣ x ) = 1 1 + e − F ( x ) = 1 1 + e − 0.8571 = 0.7021 P(Y=1|x) = \frac{1}{1+e^{-F(x)}}= \frac{1}{1+e^{-0.8571}} = 0.7021 P(Y=1x)=1+eF(x)1=1+e0.85711=0.7021

4. 手撕GBDT二分类算法

本篇文章所有数据集和代码均在我的GitHub中,地址:https://github.com/Microstrong0305/WeChat-zhihu-csdnblog-code/tree/master/Ensemble%20Learning

4.1 用Python3实现GBDT二分类算法

需要的Python库:

pandas、PIL、pydotplus、matplotlib

其中pydotplus库会自动调用Graphviz,所以需要去Graphviz官网下载graphviz-2.38.msi安装,再将安装目录下的bin添加到系统环境变量,最后重启计算机。

由于用Python3实现GBDT二分类算法代码量比较多,我这里就不列出详细代码了,感兴趣的同学可以去我的GitHub中看一下,地址:https://github.com/Microstrong0305/WeChat-zhihu-csdnblog-code/tree/master/Ensemble%20Learning/GBDT_GradientBoostingBinaryClassifier

4.2 用sklearn实现GBDT二分类算法

import numpy as np
from sklearn.ensemble import GradientBoostingClassifier

'''
调参:
loss:损失函数。有deviance和exponential两种。deviance是采用对数似然,exponential是指数损失,后者相当于AdaBoost。
n_estimators:最大弱学习器个数,默认是100,调参时要注意过拟合或欠拟合,一般和learning_rate一起考虑。
learning_rate:步长,即每个弱学习器的权重缩减系数,默认为0.1,取值范围0-1,当取值为1时,相当于权重不缩减。较小的learning_rate相当于更多的迭代次数。
subsample:子采样,默认为1,取值范围(0,1],当取值为1时,相当于没有采样。小于1时,即进行采样,按比例采样得到的样本去构建弱学习器。这样做可以防止过拟合,但是值不能太低,会造成高方差。
init:初始化弱学习器。不使用的话就是第一轮迭代构建的弱学习器.如果没有先验的话就可以不用管

由于GBDT使用CART回归决策树。以下参数用于调优弱学习器,主要都是为了防止过拟合
max_feature:树分裂时考虑的最大特征数,默认为None,也就是考虑所有特征。可以取值有:log2,auto,sqrt
max_depth:CART最大深度,默认为None
min_sample_split:划分节点时需要保留的样本数。当某节点的样本数小于某个值时,就当做叶子节点,不允许再分裂。默认是2
min_sample_leaf:叶子节点最少样本数。如果某个叶子节点数量少于某个值,会同它的兄弟节点一起被剪枝。默认是1
min_weight_fraction_leaf:叶子节点最小的样本权重和。如果小于某个值,会同它的兄弟节点一起被剪枝。一般用于权重变化的样本。默认是0
min_leaf_nodes:最大叶子节点数
'''

gbdt = GradientBoostingClassifier(loss='deviance', learning_rate=0.1, n_estimators=5, subsample=1
                                  , min_samples_split=2, min_samples_leaf=1, max_depth=3
                                  , init=None, random_state=None, max_features=None
                                  , verbose=0, max_leaf_nodes=None, warm_start=False
                                  )

train_feat = np.array([[1, 5, 20],
                       [2, 7, 30],
                       [3, 21, 70],
                       [4, 30, 60],
                       ])
train_label = np.array([[0], [0], [1], [1]]).ravel()

test_feat = np.array([[5, 25, 65]])
test_label = np.array([[1]])
print(train_feat.shape, train_label.shape, test_feat.shape, test_label.shape)

gbdt.fit(train_feat, train_label)
pred = gbdt.predict(test_feat)

total_err = 0
for i in range(pred.shape[0]):
    print(pred[i], test_label[i])
    err = (pred[i] - test_label[i]) / test_label[i]
    total_err += err * err
print(total_err / pred.shape[0])

用sklearn中的GBDT库实现GBDT二分类算法的难点在于如何更好的调节下列参数:
在这里插入图片描述
用sklearn实现GBDT二分类算法的GitHub地址:https://github.com/Microstrong0305/WeChat-zhihu-csdnblog-code/tree/master/Ensemble%20Learning/GBDT_Classification_sklearn

5. GBDT分类任务常见的损失函数

对于GBDT分类算法,其损失函数一般有对数损失函数和指数损失函数两种:

(1)如果是指数损失函数,则损失函数表达式为:
L ( y , F ( x ) ) = e x p ( − y F ( x ) ) L(y,F(x)) = exp(-yF(x)) L(y,F(x))=exp(yF(x))
其负梯度计算和叶子节点的最佳负梯度拟合可以参看Adaboost算法过程。

(2)如果是对数损失函数,分为二元分类和多元分类两种,本文主要介绍了GBDT二元分类的损失函数。

6. 总结

在本文中,我们首先简单介绍了如何把GBDT回归算法变成分类算法的思路;然后从逻辑回归的对数损失函数推导出GBDT的二分类算法原理;其次不仅用Python3实现GBDT二分类算法,还用sklearn实现GBDT二分类算法;最后介绍了GBDT分类任务中常见的损失函数。GBDT可以完美的解决二分类任务,那么它对多分类任务是否有效呢?如果有效,GBDT是如何做多分类呢?这些问题都需要我们不停的探索和挖掘GBDT的深层原理。让我们期待一下GBDT在多分类任务中的表现吧!

7. Reference

【1】Friedman J H. Greedy function approximation: a gradient boosting machine[J]. Annals of statistics, 2001: 1189-1232.
【2】GBDT详细讲解&常考面试题要点,地址:https://mp.weixin.qq.com/s/M2PwsrAnI1S9SxSB1guHdg
【3】机器学习算法GBDT的面试要点总结-上篇,地址:https://www.cnblogs.com/ModifyRong/p/7744987.html
【4】Gradient Boosting Decision Tree,地址:http://gitlinux.net/2019-06-11-gbdt-gradient-boosting-decision-tree/
【5】GBDT算法用于分类问题 - hunter7z的文章 - 知乎,地址:https://zhuanlan.zhihu.com/p/46445201
【6】当我们在谈论GBDT:Gradient Boosting 用于分类与回归 - 余文毅的文章 - 知乎
,地址: https://zhuanlan.zhihu.com/p/25257856
【7】 GBDT原理与Sklearn源码分析-分类篇,地址:https://blog.csdn.net/qq_22238533/article/details/79192579
【8】 《推荐系统算法实践》,黄美灵著。
【9】《百面机器学习》,诸葛越主编、葫芦娃著。
【10】GBDT模型,地址:https://www.jianshu.com/p/0bc32c8e4ca8
【11】代码实战之GBDT,地址:https://louisscorpio.github.io/2018/01/19/%E4%BB%A3%E7%A0%81%E5%AE%9E%E6%88%98%E4%B9%8BGBDT/


【推荐阅读】
【1】Regression Tree 回归树
【2】深入理解提升树(Boosting Tree)算法
【3】梯度提升(Gradient Boosting)算法
【4】深入理解GBDT回归算法

已标记关键词 清除标记
<p> 本课程<span>隶属于自然语言处理</span>(NLP)<span>实战系列。自然语言处理</span>(NLP)<span>是数据科学里的一个分支,它的主要覆盖的内容是:以一种智能与高效的方式,对文本数据进行系统化分析、理解与信息提取的过程。通过使用</span>NLP以及它的组件,我们可以管理非常大块的文本数据,或者执行大量的自动化任务,并且解决各式各样的问题,如自动摘要,机器翻译,命名实体识别,关系提取,情感分析,语音识别,以及主题分割等等。 </p> <p> <span>一般情况下一个初级</span>NLP工程师的工资从15<span>万</span>-35<span>万不等,所以掌握</span>NLP技术,对于人工智能学习者来讲是非常关键的一个环节。 </p> <p> <br /> </p> <p> <br /> </p> <p> <span style="background-color:#FFE500;">【超实用课程内容】</span> </p> <p> <span>课程从自然语言处理的基本概念与基本任务出发,对目前主流的自然语言处理应用进行全面细致的讲解,</span><span>包括文本分,文本摘要提取,文本相似度,文本情感分析,文本特征提取等,同时算法方面包括经典算法与深度学习算法的结合,例如</span><span>LSTM,BiLSTM等,并结合京东电商评论分、豆瓣电影摘要提取、今日头条舆情挖掘、饿了么情感分析等过个案例,帮助大家熟悉自然语言处理工程师在工作中会接触到的</span><span>常见应用的实施的基本实施流程,从</span><span>0-1入门变成自然语言处理研发工程师。</span> </p> <p style="color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <br /> </p> <p style="color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <span style="background-color:#FFE500;">【课程如何观看?】</span> </p> <p style="color:#3A4151;font-size:14px;background-color:#FFFFFF;"> PC端:<a href="https://edu.csdn.net/course/detail/26277"></a><a href="https://edu.csdn.net/course/detail/25649">https://edu.csdn.net/course/detail/25649</a> </p> <p style="color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 移动端:CSDN 学院APP(注意不是CSDN APP哦) </p> <p style="color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 本课程为录播课,课程2年有效观看时长,大家可以抓紧时间学习后一起讨论哦~ </p> <p> <br /> </p> <p> <strong><span style="background-color:#FFE500;">【学员专</span><span style="background-color:#FFE500;">享增值服务】</span></strong> </p> <p> 源码开放 </p> <p> 课件、课程案例代码完全开放给你,你可以根据所学知识,自行修改、优化 </p> <p> 下载方式:电脑登录<a href="https://edu.csdn.net/course/detail/26277"></a><a href="https://edu.csdn.net/course/detail/25649">https://edu.csdn.net/course/detail/25649</a>,点击右下方课程资料、代码、课件等打包下载 </p> <p> <br /> </p> <p> 通过第二课时下载材料<span></span> </p> <p> <br /> </p> <p> <br /> </p>
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页