目录
老饼讲解:一步一步上手学习

【模型】一篇入门之-梯度提升树GBDT

作者 : 老饼 发表日期 : 2025-12-16 23:50:13 更新日期 : 2026-05-10 16:16:18
老饼讲解-简单易懂,干货满满,爽过嗦螺!


GBDT梯度提升树(Gradient Boosting Decision Tree)也是一种经典的boosting集成模型,它通过集成回归树来解决二分类问题,它的特点是训练过程利用了梯度来训练回归树,从而使得树模型的提升更加有效,下面我们就一起看看GBDT模型的核心原理,并用一个具体的代码例子来熟悉GBDT模型的应用。

一、GBDT集成算法

我们一步一步来理解GBDT的内容。首先,GBDT是用来解决二分类问题,也就是判断样本是正样本还是负样本。好了,下面我们先来看看GBDT模型的构成,这样可以有个初步印象:

GBDT集成算法

如图,GBDT由多棵Cart弱回归树构成,再经过学习率lr与阈值b调整后,就得到样本类别最终的判别值,下面更直接的来看看模型的数学表述,如下:

GBDT的模型表达式为:

 其中,

      :第i颗Cart回归决策树的预测值 

                :学习率,自行设定的超参数           

                       :类别的判别值,g>0时为正样本,g<0时为负样本

从模型的表达式可知,GBDT模型由多个回归树组成,将所有回归树的预测值乘以学习率lr后,加上阈值,就是模型的判别值,而判别的时候,只需要看判别值g是不是大于0,如果大于0就是正样本。

1.2. GBDT的概率输出

上面得到的是GBDT模型的判别值,如果需要得到类别的概率,就进一步将用sigmoid函数将判别值转换为概率就可以了,如下:

 

如公式所示,在GBDT的判别值上套上sigmoid函数后,就是样本属于正样本的概率了。

二、GBDT-模型训练

好了,GBDT模型的结构差不多就是这样了,从模型中我们可以看到,它需要训练的就是其中的各个Cart回归树,以及外层的阈值b,而lr则是一个预设参数,不需要训练。总的来说,就是要训练阈值b和各个各个Cart回归树,下面我们来看看它具体是如何训练的。

2.1. GBDT的损失函数

先来说说GBDT的损失函数,它采用的是对数似然损失函数,如下:

  

 其中,是第i个样本的真实值          

是第i个样本的预测值   

2.2. GBDT的训练顺序

好了,我们来看看GBDT整体的训练顺序,如下:

GBDT的前向分步训练顺序

如图所示,GBDT先训练好阈值b,然后逐棵训练回归树,直到训练完m棵回归树为止,可知,它采用的是前向分步算法训练,也就是在已有树模型集合的基础上,再逐个添加新的回归树,以此来逐步提升模型的预测效果。

2.3. GBDT是如何训练Cart回归树的

好了,我们都知道,GBDT采用逐棵树训练的方式,那么每棵回归树是如何训练的呢?

观察到损失函数是关于每个样本的预测值的函数,如果往负梯度方向移动, 将下降,基于此思路,GBDT训练新树时,将当前预测值在损失函数的负梯度,作为新树拟合值:

 GBDT-每棵树的拟合值

可知,GBDT每添加一棵回归树树,所有样本的预测值就往损失函数的负梯度方向挪一下,这就是梯度提升树GBDT,非常形象:每次都往负梯度方向增加树,逐步提升模型的精度。

事实上,GBDT“梯度提升决策树”这个命名,就非常形象地解析了GBDT算法的特性:

1、决策树 :使用一组决策树进行综合决策

2、提升   :训练时使用提升方式,逐棵逐棵训练

3、梯度   :每棵树拟合值为树集合预测值的负梯度方向 

三、GBDT算法流程

最后,一起整体来看看GBDT的具体训练算法流程。

3.1. GBDT-算法流程图

先来上个算法流程图,大家结合下面的描述来理解就好了:

GBDT-算法流程图

简单来说,GBDT就是先训练阈值b,再逐棵训练弱回归树T,最后所有的回归树就集成了GBDT模型。

3.2. GBDT-阈值b的训练

先来说说阈值b的具体训练方法。

阈值b训练时,只需要使用下述公式来计算来就可以了:

                        

              其中,是样本y值的均值。

只要将损失函数对b求驻点,就可以得到这条公式了。

3.3.GBDT-弱回归树-训练流程

好了,再来说说弱回归树的具体训练流程,如下:

1. 计算本次回归树每个样本的拟合值(即残差): 

残差的计算公式如下:
            
说明:该公式就是损失函数对的负梯度

2. 用上述残差作为每个样本的目标预测值,训练弱回归树

值得注意的是,训练回归树时需要注意,要将参数调为训练弱树。 
例如把最大分裂深度<=3就是训练弱回归树的一种策略。

3. 优化弱回归树的叶子节点

进一步优化本次回归树的预测值(即树叶子节点的取值),使本次新增的回归树能更优地降低GBDT损失值。
回归树中第k个叶子节点的预测值
取值如下:
                      
                      其中,                                            
                               
  : 指回归树第k个节点上的所有样本 
说明:该公式由损失函数L对叶子节点值求驻点即可得到。

总的来说,GBDT就是先训练好阈值b,然后逐棵训练弱回归树,每训练完一棵弱回归树时都优化它叶子节点上的取值,尽可能降低损失函数。

四、GBDT-代码实现

GBDT的原理大概就是这么回事了,下面我们借助sklearn来实现一下GBDT。

"""
本代码展示sklearn包实现GBDT梯度提升树
本代码来自《老饼讲解-机器学习》www.bbblearn.com
"""
import matplotlib.pyplot as plt
from sklearn.datasets import make_gaussian_quantiles
from sklearn.ensemble import GradientBoostingClassifier

# ----- 数据生成 --------                                                           
# 生成2维正态分布,数据按分位数分为两类,500个样本,2个样本特征,协方差系数为2          
X,y=make_gaussian_quantiles(n_classes=2,cov=2.0,n_samples=500,n_features=2,random_state=1) # 生成训练样本数据

#--------------模型训练与预测---------------------
clf = GradientBoostingClassifier(n_estimators=100,learning_rate=0.1,random_state=0)        # 初始化GBDT模型
clf.fit(X, y)                                                                              # 模型训练
pred  = clf.predict(X)                                                                     # 模型预测的类别
proba = clf.predict_proba(X)                                                               # 模型预测的概率

# ----------------- 打印结果-------------------------
fig, axes = plt.subplots(2, 1,figsize=(10, 6))                                             # 初始化画布
plt.subplots_adjust(wspace=0.2, hspace=0.3)                                                # 调整画布子图间隔
axes[0].scatter(X[:, 0], X[:, 1], c=y)                                                     # 画出样本与真实类别
axes[0].set_title('sample-true-class')                                                     # 设置子图的标题
axes[1].scatter(X[:, 0], X[:, 1], c=pred)                                                  # 画出样本与预测类别
axes[1].set_title('sample-predict-class')                                                  # 设置子图的标题
plt.show()                                                                                 # 显示画布	
print("\n----前10个样本预测结果-----:\n",proba[1:10,1])                                    # 前10个样本预测值

代码运行结果如下:

GBDT对样本的分类结果

GBDT的预测结果

从图中可以看到,模型的预测类别与真实类别几乎是一致的。

总结

总的来说,GBDT就是一种Boosting算法,它集成多棵回归树来解决二分类问题。它的特点是每棵树训练时的拟合目标是树集合预测值的负梯度方向,所以就称为“梯度提升决策树”。



图标 评论
添加评论