集成学习——梯度提升树(GBDT)

本文介绍了梯度提升树(GBDT)的基本原理,作为集成学习的成员,GBDT通过加法模型和残差减小策略迭代构建弱分类器。在sklearn中,GBDT分为分类和回归两种实现,主要参数包括n_estimators、learning_rate、subsample等,这些参数对模型的拟合和防止过拟合起关键作用。文中还提及了不同损失函数的选择及其影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

集成学习——梯度提升树(GBDT)

1 模型算法介绍

GBDT 也是集成学习 Boosting 家族的成员,通过采用加法模型,不断减小训练过程中产生的残差算法。即通过多轮迭代,每轮迭代生成一个弱分类器,并在上一轮分类器残差的基础上进行训练,但是弱学习器限定了只能使用 CART 回归树模型,且迭代思路与 Adaboost(利用前一轮迭代弱学习器的误差率来更新训练集的权重)有所不同。
GBDT 采用的是加法模型,这就要保证每一个弱学习器的输出结果进行加减是有意义的。但不能把 GBDT 看成很多棵分类树,因为分类树的输出结果是不同的类别,进行加减无意义,弱学习器只有采用回归树才有意义。GBDT 的核心就在于,每一个弱学习器学习的是上一轮迭代结论和的残差,即残差与预测值之和等于真实值,例如 A 的真实年龄是 18 岁,第一棵树的预测年龄是 12 岁,差了 6 岁,即残差为 6 岁;那么在第二棵树里我们把 A 的年龄设为 6 岁去学习,如果第二棵树真的能把 A 分到 6 岁的叶子节点,那累加两棵树的结论就是 A 的真实年龄;如果第二棵树的结论是 5 岁,则 A 仍然存在 1 岁的残差,第三棵树里 A 的年龄就变成1岁,如果迭代轮数还没有完,可以继续迭代,每一轮迭代拟合的岁数误差都会减小。
模型如下:

F m ( x ) = ∑ m = 1 M T ( x ; θ m ) F_m(x)=\sum_{m=1}^MT(x;\theta_m) Fm(x)=m=1MT(x;θm)

M M M 表示模型训练的轮数,每轮产生一个弱学习器 T ( x ; θ m ) T(x;\theta_m) T(x;θm) θ m \theta_m θm 表示迭代之后的残差,则残差的求解可以表示成如下形式:

θ ^ m = a r g min ⁡ ⎵ θ m ∑ i = 1 N L ( y i , F m − 1 ( x i ) + T ( x i ; θ m ) ) \hat{\theta}_m=\underbrace{arg\min}_{\theta_m}{\sum_{i=1}^NL(y_i,F_{m-1}(x_i)+T(x_i;\theta_m))} θ^m=θm argmini=1NL(yi,Fm1(xi)+T(xi;θm))

其中 F m − 1 ( x i ) F_{m-1}(x_i) Fm1(xi) 为当前的模型, L L L 表示损失函数。
我们知道损失函数的值越大,说明模型越容易出错,如果我们的模型能够让损失函数持续的下降,则说明我们的模型在不停的改进,而最好的方式就是让损失函数在其梯度的方向上下降。损失函数的负梯度为:

∂ L ( y i , F m ( x i ) ) ∂ F m ( x i ) ∣ F ( x ) = F m − 1 ( x i ) \left.\frac{\partial L(y_i,F_{m}(x_i))}{\partial F_{m}(x_i)}\right|_{F(x)=F_{m-1}(x_i)} Fm(xi)L(yi,Fm(xi))F(x)=Fm1(xi)

结合 θ ^ m \hat{\theta}_m θ^m 的求解公式,可以求出本轮的弱学习器 T ( x ; θ m ) T(x;\theta_m) T(x;θm),本轮得到的强学习器为:

F m ( x ) = F m − 1 ( x ) + T ( x ; θ m ) F_m(x)=F_{m-1}(x)+T(x;\theta_m) Fm(x)=Fm1(x)+T(x;θm)

2 sklearn 中的实现

在sklearn 中,集成学习中的 GBDT 算法同样分为两类,即分类的 GradientBoostingClassifier ,回归的 GradientBoostingRegressor。类似于 Adaboost,其参数可以分为 Boosting 框架参数与弱学习器参数两类。下面以 GradientBoostingClassifier 为例对主要参数说明,详细的参数可以查看官方参考

class sklearn.ensemble.GradientBoostingClassifier(loss=’deviance’, learning_rate=0.1, n_estimators=100, subsample=1.0, criterion=’friedman_mse’, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3, min_impurity_decrease=0.0, min_impurity_split=None, init=None, random_state=None, max_features=None, verbose=0, max_leaf_nodes=None, warm_start=False, presort=’auto’, validation_fraction=0.1, n_iter_no_change=None, tol=0.0001)

主要参数说明
n_estimators: 也就是弱学习器的最大迭代次数,或者说最大的弱学习器的个数。一般来说 n_estimators 太小,容易欠拟合,n_estimators 太大,又容易过拟合,一般选择一个适中的数值。默认是 100。在实际调参的过程中,常常需要将 n_estimators 和下面介绍的参数 learning_rate 一起考虑。
learning_rate: 即每个弱学习器的权重缩减系数,也称作步长,其取值范围为 0~1。对于同样的训练集拟合效果,较小的步长意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。所以这两个参数 n_estimators 和 learning_rate 要一起调参。一般来说,可以从一个小一点的步长开始调参,默认是 0.1。
subsample: 即子采样,取值为 (0,1]。注意这里的子采样和随机森林不一样,随机森林使用的是放回抽样,而这里是不放回抽样。如果取值为 1,则全部样本都使用,等于没有使用子采样。如果取值小于 1,则只有一部分样本会去做 GBDT 的决策树拟合。选择小于 1 的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。推荐在 [0.5, 0.8] 之间,默认是 1.0,即不使用子采样。
loss: 即 GBDT 算法中的损失函数。分类模型和回归模型的损失函数是不一样的。对于分类模型,有对数似然损失函数 deviance 和指数损失函数 exponential 两者输入选择。默认是对数似然损失函数 deviance 。一般来说,推荐使用默认的 deviance 。它对二元分离和多元分类各自都有比较好的优化。而指数损失函数等于把我们带到了 Adaboost 算法。对于回归模型,有均方差 ls,绝对损失 lad, Huber 损失 huber 和分位数损失 quantile 。默认是均方差 ls 。一般来说,如果数据的噪音点不多,用默认的均方差 ls 比较好。如果是噪音点较多,则推荐用抗噪音的损失函数 huber 。而如果我们需要对训练集进行分段预测的时候,则采用 quantile 。
alpha:这个参数只有 GradientBoostingRegressor 有,当我们使用 Huber 损失 huber 和分位数损失 quantile 时,需要指定分位数的值。默认是 0.9,如果噪音点较多,可以适当降低这个分位数的值。

接下来以 iris 数据集为例进行说明:

from sklearn.datasets import load_iris 
from sklearn.model_selection import train_test_split 
from sklearn.ensemble import GradientBoostingClassifier

iris = load_iris() 
iris_data = iris.data # 数据集 
iris_labels = iris.target # 对应的分类标签
 
# 使用train_test_split对数据集按比例进行随机抽取,本文按37开进行抽取 
X_train, X_test, Y_train, Y_test = train_test_split(iris_data, iris_labels, test_size=0.3, random_state=0) 

# 定义分类器对象 
clf = GradientBoostingClassifier(n_estimators=100)

# 调用所定义的分类器的训练方法,主要接收两个参数:训练数据集及训练标签 
clf.fit(X_train,Y_train) 

#调用该对象的测试方法,主要接收一个参数:测试数据集 
Y_predict = clf.predict(X_test) 

#计算各测试样本属于不同类的概率预测值 
probility = clf.predict_proba(X_test)

# 调用打分方法,计算模型在测试集上的准确率 
score = clf.score(X_test,Y_test)

3 参考资料

1 https://blog.csdn.net/w28971023/article/details/8240756
2 https://www.cnblogs.com/ModifyRong/p/7744987.html
3 李航的统计学习方法
4 周志华的机器学习

### 梯度提升树(GBDT)原理 梯度提升树是一种集成学习方法,其核心在于构建一系列弱分类器(通常是决策树),并通过迭代方式逐步减少损失函数来增强整体模型性能。具体来说,在每次迭代过程中,新加入的一棵树会专注于修正前一轮预测中的错误。 #### 数学公式推导 对于一个由 \( M \) 颗树组成的提升树模型,可以表示为: \[ f_M(x) = \sum_{m=1}^{M} T(x; \varTheta_m)\tag{11-1}\label{eq:boosting-tree-model}[^3] 其中: - \(f_M(x)\) 表示最终的预测结果; - \(T(x;\varTheta_m)\) 是第\( m \)棵回归树对应的叶节点权重向量\(\varTheta_m\)所决定的输出值; 为了最小化总体误差,采用加法模型的形式逐次逼近最优解。即在每一步都寻找能够最大程度降低当前残差平方和的新基函数(这里是单棵CART回归树)。设初始估计值为常数项c0,则有: \[ F_0(x)=argmin_c{\frac {1}{N}}\sum _{{i=1}}^{N}(y_i-c)^2=c_0=\bar y,\quad where\ N=len(y),\ and\ \bar y={\frac {\sum _{{i=1}}^{N}y_i}{N}}.\nonumber \] 接着依次更新后续各步的近似值Fi(x),使得目标函数L达到极小化状态: \[F_k(x)=F_{k−1}(x)+h_k(x).\nonumber \] 这里hk(x)代表新增加的那一部分贡献——也就是我们所说的“伪残留”。它实际上就是利用前面提到的方法拟合出来的关于真实标签yi与现有预测之间差距的信息。当涉及到具体的优化过程时,则需考虑不同的损失函数形式以及相应的梯度下降策略来进行求解。 ```python from sklearn.ensemble import GradientBoostingClassifier import numpy as np # 构造简单的二元分类数据集用于演示目的 X_train = np.array([[1], [2], [3]]) y_train = np.array([0, 1, 0]) clf = GradientBoostingClassifier(n_estimators=3, learning_rate=1.0, max_depth=1, random_state=0) model = clf.fit(X_train, y_train) print(model.predict_proba(np.array([[1]]))) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值