8.GDBT算法原理及实现

GBDT是一种基于梯度提升的决策树算法,通过不断迭代弱学习器来降低损失函数。XGBoost是GBDT的优化版,引入正则项并采用二阶导数信息,提高了效率和泛化能力。XGBoost在决策树构建时进行预剪枝,支持并行计算,适合大规模数据处理。

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

GBDT

一、概念


   G B D T ( G r a d i e n t    B o o s t i n g    D e c i s i o n    T r e e ) GBDT(Gradient \; Boosting \; Decision \;Tree) GBDT(GradientBoostingDecisionTree) 梯度提升决策树,是 G r a d i e n t    B o o s t i n g Gradient \; Boosting GradientBoosting 框架下使用的较多的一个模型,且在 G B D T GBDT GBDT 中,其基学习器是分类回归树,也就是 C A R T CART CART(详见 3.决策树原理与数学建模实战),且使用的是 C A R T CART CART 树中的回归树。

  决策树分为两大类:回归树与分类树。前者用于预测实数值,后者用于分类标签值,其区别是,前者的结果加减是有意义的,如, 10 元 + 3 元 = 13 元 10元+3元=13元 10+3=13,后者的加减是无意义的,如: 男 + 女 = ? 男+女=? +=

   G B D T GBDT GBDT 的核心在于累加所有树的结果作为最终结果。而分类树的结果显然是没有办法累加的,所以 G B D T GBDT GBDT 中的树都是回归树不是分类树(尽管 G B D T GBDT GBDT 也可以用作分类但不代表所使用的树是分类树)。

二、算法原理

2.1 原理

   G r a d i e n t    B o o s t i n g Gradient \; Boosting GradientBoosting 集成了 B o o s t i n g Boosting Boosting 的思想,利用加法模型与前向分布算法实现学习的优化过程。每个基学习器在上一轮学习器的基础上进行训练。对弱学习器 (弱分类器)的要求一般足够简单,并且是低方差和高偏差的(欠拟合)。因为训练的过程就是通过降低偏差不断提高最终学习器的精度。

  它根据当前模型损失函数的负梯度信息来训练新加入的弱分类器,然后将训练好的弱分类器以累加的形式结合到现有的模型中。其算法伪码如下:

2.2 算法流程


A l g o r i t h m : Algorithm: Algorithm:


  1. F 0 ( x ) = arg ⁡ min ⁡ p ∑ i = 1 N L ( y i , ρ ) F_0(x) = \arg \min_p \sum\limits^N_{i=1}L(y_i, \rho) F0(x)=argminpi=1NL(yi,ρ)
  2. F o r    m = 1    t o    M    d o : For \; m = 1 \; to \; M \; do: Form=1toMdo:
  3. y ~ i = [ ∂ L ( y i ) , F ( x i ) ∂ F ( x i ) ] F ( x ) = F m − 1 ( X ) i = 1 , … , M \quad \tilde y_i = [\frac{\partial L(y_i), F(x_i)}{\partial F(x_i)}]_{F(x) = F_{m-1(X)}} \quad i = 1, \dots, M y~i=[F(xi)L(yi),F(xi)]F(x)=Fm1(X)i=1,,M
  4. a m = arg ⁡ min ⁡ α , β ∑ i = 1 N [ y ~ i = β h ( x i : a ) ] 2 \quad a_m = \arg \min_{\alpha, \beta}\sum\limits^{N}_{i=1}[\tilde y_i = \beta h(x_i :a)]^2 am=argminα,βi=1N[y~i=βh(xi:a)]2
  5. ρ m = arg ⁡ min ⁡ ρ ∑ i = 1 N L ( y i , F m − 1 ( x i ) + ρ h ( x i : a m ) ) \quad \rho _m = \arg \min_\rho \sum\limits^{N}_{i=1}L(y_i, F_{m-1}(x_i)+ \rho h(x_i : a_m)) ρm=argminρi=1NL(yi,Fm1(xi)+ρh(xi:am))
  6. F m ( x ) = F m − 1 ( x ) + ρ m h ( x : a m ) \quad F_m(x) = F_{m-1}(x) + \rho_m h(x:a_m) Fm(x)=Fm1(x)+ρmh(x:am)
  7. e n d    F o r end \; For endFor
  8. e n d    A l g o r i t h m end \; Algorithm endAlgorithm

   G B D T GBDT GBDT核心就在于,每一棵树学习的是之前所有树结论和的残差,这个残差就是一个加预测值后能得真实值的累加量。

  比如 A A A 的真实年龄是 18 18 18 岁,但第一棵树的预测年龄是12岁,差了6岁,即残差为6岁。那么在第二棵树里我们把 A A A 的年龄设为6岁去学习,如果第二棵树真的能把 A A A 分到6岁的叶子节点,那累加两棵树的结论就是 A A A 的真实年龄;如果第二棵树的结论是5岁,则 A A A 仍然存在 1 岁的残差,第三棵树里 A A A 的年龄就变成1岁。如果我们的迭代轮数还没有完,可以继续迭代下面每一轮迭代,拟合的岁数误差都会减小。

2.3 目标函数

  模型一共训练 M M M 轮,每轮产生一个弱学习器 T ( x ; θ m ) T(x;θ_m) Tx;θm)。弱学习器的目标函数可以表示为:
θ m ^ = ∑ i = 1 arg ⁡ min ⁡ N L ( y i , F m − 1 ( x i ) + T ( x ; θ m ) ) \hat{\theta_m} = \sum\limits^{\arg \min N}_{i=1}L(y_i, F_{m-1}(x_i) + T(x; \theta_m)) θm^=i=1argminNL(yi,Fm1(xi)+T(x;θm))
   F m − 1 ( x i ) F_{m−1}(x_i) Fm1(xi) 为当前的模型, G B D T GBDT GBDT 通过经验风险极小化来确定下一个弱学习器的参数。具体使用到的损失函数的选择也就是这里的 L L L,主要有平方损失函数, 0 − 1 0-1 01 损失函数,对数损失函数等等。如果我们选择平方损失函数,那么这个差值其实就是我们平常所说的残差。

  目标:第一个是希望我们的损失函数能够不断减小;第二个是希望我们的损失函数能够尽可能快地减小。

  让损失函数沿着负梯度方向的下降,是 G B D T GBDT GBDT G B GB GB 另外一个核心。利用损失函数的负梯度在当前模型的值,作为回归提升树算法中的残差的近似值去拟合一个回归树。 G B D T GBDT GBDT 每轮迭代的时候,都去拟合损失函数在当前模型下的负梯度。

  这样每轮训练的时候都能够让损失函数尽可能快的减小,尽快地收敛达到局部最优或者全局最优。

2.4 梯度提升于梯度下降

  两者对比可用下表表示:

梯度提升函数空间 F F F F = F t − 1 − ρ t ∇ F L ∣ F = F t − 1 F = F_{t-1} - \rho_t\nabla_FL|_{F=F_{t-1}} F=Ft1ρtFLF=Ft1 L = ∑ L ( y i , F ( x i ) ) L=\sum\limits L(y_i, F(x_i)) L=L(yi,F(xi))
梯度下降参数空间 W W W w t = w t − 1 − ρ t ∇ w L ∣ w = w t − 1 w_t = w_{t-1} - \rho_t \nabla_wL|_{w=w_{t-1}} wt=wt1ρtwLw=wt1 L = ∑ L ( y i , f w ( w i ) ) L = \sum\limits L(y_i,f_w(w_i)) L=L(yi,fw(wi))

  可以发现,两者都是在每一轮迭代中,利用损失函数相对于模型的负梯度方向的信息来对当前模型进行更新,只不过在梯度下降中,模型是以参数化形式表示,从而模型的更新等价于参数的更新。而在梯度提升中,模型并不需要进行参数化表示,而是直接定义在函数空间中,从而大大扩展了可以使用的模型种类。

三、Python实现

   G B D T GBDT GBDT 封装在 sklearn.ensemble 中,其分类器 GradientBoostingClassifier 与回归器 GridientBoostingRegressor 接口皆在此包内。

from sklearn.datasets import load_boston
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

X, y = load_boston(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.3, random_state=42)

gbdt = GradientBoostingRegressor()
gbdt.fit(X_train, y_train)

plt.plot(y_test, 'r', label='True')
plt.plot(gbdt.predict(X_test), 'b', label='Predict')
plt.legend()
plt.savefig('E:/Computer/Desktop/数模/有监督学习/集成学习/gbdt.png', dpi=400)

  拟合效果如下:

在这里插入图片描述

四、XGBoost

4.1 概念

   X G B o o s t XGBoost XGBoost 本质上还是 G B D T GBDT GBDT,但是把速度和效率做到了极致;

  不同于传统的 G B D T GBDT GBDT 方式,只利用了一阶的导数信息, X G B o o s t XGBoost XGBoost 对损失函数做了二阶的求导 (泰勒展开),并在目标函数之外加入了正则项整体求最优解,用以权衡目标函数的下降和模型的复杂程度,避免过拟合。

   X G B o o s t XGBoost XGBoost 继承了 G B D T GBDT GBDT ,模型也是 C A R T CART CART , 但不仅限于回归树。因此还是沿用了加法模型,但是在目标函数上有所区别。

4.2 区别与联系

  原始的 G B D T GBDT GBDT 算法基于经验损失函数的负梯度来构造新的决策树,只是在决策树构建完成后再进行剪枝。而 X G B o o s t XGBoost XGBoost 在决策树构建阶段就加入了正则项,即:
L t = ∑ i l ( y i , F t − 1 ( x i ) ) + Ω f ( x t ) L_t = \sum\limits_il(y_i, F_{t-1}(x_i)) + \Omega f(x_t) Lt=il(yi,Ft1(xi))+Ωf(xt)
  其中 F t − 1 ( x i ) F_{t-1}(x_i) Ft1(xi) 表示现有的 t − 1 t-1 t1 棵树的最优解,关于树结构的正则化项定义为:
Ω ( f t ) = γ T + 1 2 λ ∑ j = 1 T w j 2 \Omega (f_t) = \gamma T + \frac 12 \lambda\sum\limits^T_{j=1}w^2_j Ω(ft)=γT+21λj=1Twj2
  其中 T T T 为叶子节点个数, w j w_j wj 表示第 j j j 个叶子节点的预测值。对该损失函数在 F t − 1 F_{t-1} Ft1 处进行二阶泰勒展开可以推导出:
L t ≈ L t ~ = ∑ j = 1 T [ G j w j + 1 2 ( H j + λ ) w j 2 ] + γ T L_t \approx \tilde{L_t} = \sum\limits^T_{j=1}[G_jw_j + \frac 12 (H_j + \lambda)w_j^2] + \gamma T LtLt~=j=1T[Gjwj+21(Hj+λ)wj2]+γT
  其中 T T T 为决策树 f t f_t ft 中叶子节点的个数, G j = ∑ i ∈ I j ∇ F t − 1 I ( y i , F t − 1 ( x i ) ) G_j = \sum\limits_{i \in I_j}\nabla_{F_{t-1}}I(y_i, F_{t-1}(x_i)) Gj=iIjFt1I(yi,Ft1(xi)) H j = ∑ j ∈ I j ∇ F t − 1 2 l ( y i , F t − 1 ( x i ) ) H_j = \sum\limits_{j \in I_j}\nabla^2_{F_{t-1}}l(y_i, F_{t-1}(x_i)) Hj=jIjFt12l(yi,Ft1(xi)) I j I_j Ij 表示所有属于叶子节点 j j j 的样本的索引的结合。

  假设决策树的结构已知,通过令损失函数相当于 w j w_j wj 的导数为 0 可以求出在最小化损失函数的情况下各个叶子节点上的预测值
w j ∗ = − G j H j + λ w_j^* = - \frac{G_j}{H_j + \lambda} wj=Hj+λGj
  然而从所有的树结构中寻找最优的树结构是一个 N P − h a r d NP-hard NPhard 问题,因此在实际中往往采用贪心法来构建出一个次优的树结构,基本思想是从根节点开始,每次对一个叶子节点进行分裂,针对每一种可能的分裂,根据特定的准则选取最优的分裂。不同的决策树算法采用不同的准则,如 I D 3 ID3 ID3 采用信息增益, C 4.5 C4.5 C4.5 为了克服信息增益中容易偏向取值较多的特征而采用信息增益比, C A R T CART CART 算法使用基尼指数和平方误差, X G B o o s t XGBoost XGBoost 也有特定的准则来选取最优分裂。

  通过将预测值代入到损失函数中可求得损失函数的最小值
L t ∗ ~ = − 1 2 ∑ j = 1 T G j 2 H j + λ + γ T \tilde {L^*_t} = - \frac 12 \sum\limits^T_{j=1}\frac{G^2_j}{H_j+\lambda} + \gamma T Lt~=21j=1THj+λGj2+γT
  容易计算出分裂前后损失函数的差值为:
G a i n = G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ − γ Gain = \frac{G_L^2}{H_L+\lambda} + \frac{G_R^2}{H_R+\lambda} - \frac{(G_L + G_R)^2}{H_L+H_R+\lambda} - \gamma Gain=HL+λGL2+HR+λGR2HL+HR+λ(GL+GR)2γ
   X G B o o s t XGBoost XGBoost 采用最大化这个差值作为准则来进行决策树的构建,通过遍历所有特征的所有取值,寻找使得损失函数前后相差最大时对应的分裂方式,此外,由于损失函数前后存在差值一定为正的限制,此时 γ \gamma γ 起到了一定的预剪枝效果。

  除了算法上与传统的 G B D T GBDT GBDT 有一些不同外, X G B o o s t XGBoost XGBoost 还在工程实现上做了大量优化,总的来说,二者联系可以分为以下几个部分:

  1. G B D T GBDT GBDT 是机器学习算法, X G b o o s t XGboost XGboost 是该算法的工程实现;
  2. 在使用 C A R T CART CART 作为基分类器时, X G B o o s t XGBoost XGBoost 显式的加入了正则项来控制模型的复杂度,有利于防止过拟合,从而提高模型的泛化能力;
  3. G B D T GBDT GBDT 在模型训练时只使用了代价函数的一阶导数信息, X G B o o s t XGBoost XGBoost 对代价函数进行二阶泰勒展开,可以同时使用一阶和二阶导数;
  4. 传统 G B D T GBDT GBDT 采用 C A R T CART CART 作为基分类器, X G B o o s t XGBoost XGBoost 支持多种类型的基分类器,如线性分类器;
  5. 传统的 G B D T GBDT GBDT 在每轮迭代时使用全部的数据, X G B o o s t XGBoost XGBoost 则采用了与随机森林相似的策略,支持对数据进行采样;
  6. 传统 G B D T GBDT GBDT 没有设计对缺失值进行处理, X G B o o s t XGBoost XGBoost 能够自动学习出缺失值的处理策略。

四、小结

G B D T GBDT GBDT:


优点:

  1. 可以灵活处理各种类型的数据,包括连续值和离散值;
  2. 在相对较少的调参时间情况下,预测的准确率也可以比较高,这个是相较于 S V M SVM SVM 的;
  3. 使用一些健壮的损失函数,对异常值的鲁棒性非常强,比如 H u b e r Huber Huber 损失函数和 Q u a n t i l e Quantile Quantile 损失函数;
  4. 很好的利用弱分类器进行级联;
  5. 充分考虑的每个分类器的权重;

缺点:

对异常样本敏感,异常样本在迭代中可能获得较高的权重,影响最终的强学习器的预测准确性。


X G B o o s t : XGBoost: XGBoost:


优点:

  1. 对缺失值不敏感,可以给缺失值自动划分方向;
  2. 可以引入阈值限制树分裂,控制树的规模,防止过拟合问题;
  3. 分裂依据分开后与未分前的差值增益,不用每个节点排序算增益,减少计算量,可以并行计算

缺点:

  1. 当预测器有很多类别时,容易过拟合;
  2. 参数过多,调参困难;
  3. 如果采取精确搜索算法对内存消耗过大,且不支持分布式。

值不敏感,可以给缺失值自动划分方向;
2. 可以引入阈值限制树分裂,控制树的规模,防止过拟合问题;
3. 分裂依据分开后与未分前的差值增益,不用每个节点排序算增益,减少计算量,可以并行计算

缺点:

  1. 当预测器有很多类别时,容易过拟合;
  2. 参数过多,调参困难;
  3. 如果采取精确搜索算法对内存消耗过大,且不支持分布式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值