(八)GBDT的原理及实现

本文介绍了GBDT(GradientBoostingDecisionTree)的数学原理、解决分类和回归问题的方法,以及如何通过sklearn库在Python中实现。它详细讲述了弱学习器、损失函数调整、CART树的构建和迭代过程。

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

(八)GBDT

本系列重点在浅显易懂,快速上手。不进行过多的理论讲解:也就是不去深究what,而是关注how。全文围绕以下三个问题展开:

1)长什么样?

2)解决什么问题?

3)怎么实现?

​ 3.1)从数学讲,原理

​ 3.2)从代码上讲,如何掉包实现

1 长什么样

GBDT=Gradient Boosting+CART树

gradient boosting decision tree 梯度提升决策树,有多个若学习器组成,弱学习器的通常是层数较少的CART回归树,单个弱学习器,因层数叫浅,所以偏差较大,方差小,最终的GBDT的输出是每个若学习器的输出的加和。如下图所示,为什么是加和?看下文的解释。

备注:所有GBDT算法中,底层都是回归树。

GBDT也是Boosting算法的一种,但是和AdaBoost算法不同;区别如下:
AdaBoost算法是利用前一轮的弱学习器的误差来更新样本权重值,然后一轮一轮的迭代;GBDT也是迭代,但是GBDT要求弱学习器必须是回归CART模型,而且GBDT在模型训练的时候,是要求模型预测的样本损失尽可能的小

要迭代所少次,(就是需要多少棵树),需要调参,分类看准确率召回率系列的指标。回归看MSE系列的指标。

给定一个步长step,在构建下一棵树的时候使用step*残差值作为输入值,这种方式可以减少过拟合的发生。

在这里插入图片描述

2 解决什么问题

可以解决分类或回归问题。

3 怎么实现

3.1 数学原理(回归算法)

在这里插入图片描述

(1)初始化第一个若学习器,得到常熟函数 f 0 ( x ) f_0(x) f0(x)

f 0 ( x ) = a r g m i n c ∑ i = 1 N L ( y i , c ) f_0(x) = arg min_c\sum^{N}_{i=1}L(y_i,c) f0(x)=argminci=1NL(yi,c)

损失函数L是误差平方和损失函数。凸函数,要求极值,可以求导,求解导函数为0的点。过程如下。

∑ i = 1 N ∂ L ( y i , c ) ) ∂ c = ∑ i = 1 N ∂ ( 1 2 ( y i − c ) 2 ) ∂ c = ∑ i = 1 N c − y i = 0 \begin{align*}\sum_{i=1}^N\frac{\partial L(y_i,c))}{\partial c} &=\sum_{i=1}^N\frac{\partial(\frac12(y_i-c)^2)}{\partial c}\\ & =\sum_{i=1}^Nc-y_i=0\\ \end{align*} i=1NcL(yi,c))=i=1Nc(21(yic)2)=i=1Ncyi=0

不难得到:

c = ( ∑ i = 1 N y i ) / N c=(\sum^{N}_{i=1}y_i)/N c=(i=1Nyi)/N

(2)构建新的样本集,GBDT算法是通过改变y的值,来构建新的样本集,具体的是将标签y,替换为残差 γ γ γ

r i , m = − [ ∂ L ( y i , f ( x i ) ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) r_{i,m}=-\left[\frac{\partial L(y_i,f(x_i)))}{\partial f(x_i)}\right]_{f(x)=f_{m-1}(x)} ri,m=[f(xi)L(yi,f(xi)))]f(x)=fm1(x)

当回归问题是,采用误差平方和损失函数(MSE),此时

r i , m = − ∂ ( 1 / 2 ( y i − f m − 1 ( x ) ) 2 ) ∂ f m − 1 ( x ) = y i − f m − 1 ( x ) r_{i,m}=-\frac{\partial(1/2(y_i-f_{m-1}(x))^2)}{\partial f_{m-1}(x)}\\ =y_i-f_{m-1}(x) ri,m=fm1(x)(1/2(yifm1(x))2)=yifm1(x)

(3)用上一步,得到的新数据集构建第一个弱学习器,CART回归树,(CART回归树的实现原理,见本系列第5篇博客,(五)决策树)。最终得到的叶子节点如下:

Υ m , j = a r g   m i n Υ ∑ x i ∈ R m , j L ( y i , f m − 1 ( x i ) + Υ ) = a r g   m i n Υ ∑ x i ∈ R m , j L ( Υ i , m − 1 , Υ ) 凸函数,求极值,通过求导,让导函数为 0 的方式实现: ∑ i = 1 N ∂ L ( Υ i , m − 1 , Υ ) ∂ Υ = ∑ i = 1 N ∂ ( 1 2 ( Υ i , m − 1 − Υ ) 2 ) ∂ Υ = ∑ i = 1 N Υ − Υ i , m − 1 = 0 Υ = ( ∑ i = 1 N Υ i , m − 1 ) / N 所以,第一个若学习的输出为 Υ 1 , j I ( x i ∈ R 1 , j ) \begin{align*} Υ_{m,j}&=arg \ min_Υ\sum_{x_i∈R_{m,j}}L(y_i,f_{m-1}(x_i)+Υ)\\ &=arg \ min_Υ\sum_{x_i∈R_{m,j}}L(Υ_{i,m-1},Υ)\\\\ 凸函数,求极值,通过求导,让导函数为0的方式实现:\\ \\ \sum_{i=1}^N\frac{\partial L(Υ_{i,m-1},Υ)}{\partial Υ} &=\sum_{i=1}^N\frac{\partial(\frac12(Υ_{i,m-1}-Υ)^2)}{\partial Υ}\\ & =\sum_{i=1}^N Υ-Υ_{i,m-1}=0\\ Υ&=(\sum^{N}_{i=1}Υ_{i,m-1})/N\\ 所以,第一个若学习的输出为Υ_{1,j}I(x_i∈R_{1,j}) \end{align*}\\ Υm,j凸函数,求极值,通过求导,让导函数为0的方式实现:i=1NΥL(Υi,m1,Υ)Υ所以,第一个若学习的输出为Υ1,jI(xiR1,j)=arg minΥxiRm,jL(yi,fm1(xi)+Υ)=arg minΥxiRm,jL(Υi,m1,Υ)=i=1NΥ(21(Υi,m1Υ)2)=i=1NΥΥi,m1=0=(i=1NΥi,m1)/N

(4) 更新强学习器,

f 1 ( x ) = f 0 ( x ) + l r ∗ ∑ Υ 1 , j I ( x i ∈ R 1 , j ) f_1(x)=f_0(x)+lr*\sum Υ_{1,j}I(x_i∈R_{1,j}) f1(x)=f0(x)+lrΥ1,jI(xiR1,j)

(5)再次构建新的数据集,重复(2)(3)(4)的过程,得到最总的强学习器。

f ( x ) = f M ( x ) = f 0 ( x ) + l r ∗ ∑ m = 1 M ∑ j = 1 J Υ m , j I ( x i ∈ R m , j ) ,其中 l r 是学习率 f(x)=f_M(x)=f_0(x)+lr*\sum_{m=1}^M\sum _{j=1}^JΥ_{m,j}I(x_i∈R_{m,j}),其中lr是学习率 f(x)=fM(x)=f0(x)+lrm=1Mj=1JΥm,jI(xiRm,j),其中lr是学习率

3.2数学原理(分类算法)

在这里插入图片描述

回归问题中,构建新数据集用的是负梯度值,就是用真实值减去预测值,但是在分类问题中,真实值和预测值都是类别,类别之间的相减是没有意义的。一种解决方案是,采用逻辑回归算法中的对数损失函数,用结果的预测概率值和真实概率值的差值作为残差。

逻辑回归的对数损失函数为:

ℓ ( θ ) = log ⁡ L ( θ ) = ∑ i = 1 m ( y ( i ) log ⁡ h θ ( x ( i ) ) + ( 1 − y ( i ) ) log ⁡ ( 1 − h θ ( x ( i ) ) ) ) \ell(\theta)=\log L(\theta)=\sum_{i=1}^{m}\left(y^{(i)}\log h_{\theta}\left(x^{(i)}\right)+\left(1-y^{(i)}\right)\log\left(1-h_{\theta}\left(x^{(i)}\right)\right)\right) (θ)=logL(θ)=i=1m(y(i)loghθ(x(i))+(1y(i))log(1hθ(x(i))))

(1)初始化第一个弱学习器

对上式求导,领导数为0

∂ L ( y i , F ( x i ) ) ∂ F ( x i ) = y i − 1 1 + e − F ( x i ) ∑ ( y i − 1 1 + e − F 0 ( x ) ) = 0 F 0 ( x ) = l o g p ( y = 1 ) 1 − p ( y = 1 ) \begin{align*} &\frac{\partial L(y_i,F(x_i))}{\partial F(x_i)}=y_i-\frac1{1+e^{-F(x_i)}}\\\\ &\sum(y_i-\frac1{1+e^{-F_0(x)}})=0\\\\ &F_0(x)= log\frac{p(y=1)}{1-p(y=1)}\\ \end{align*} F(xi)L(yi,F(xi))=yi1+eF(xi)1(yi1+eF0(x)1)=0F0(x)=log1p(y=1)p(y=1)
(2)计算负梯度,伪残差

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 ) \begin{align*} r_{m,i}&=-\bigg|\frac{\partial L(y_{i},F(x_{i}))}{\partial F(x_{i})}\bigg|_{F(x)=F_{m-1}(x)}\\ &=y_{i}-\frac{1}{1+e^{-F(x_{i})}}\\ \end{align*} rm,i= F(xi)L(yi,F(xi)) F(x)=Fm1(x)=yi1+eF(xi)1
(3)利用上面求解得到的残差值,形成新的训练集 ( x i , r m , i ) (x_i,r_{m,i}) (xi,rm,i),训练CART回归树。

(4)训练的cart回归树对应的叶子节点区域为 R m , j R_{m,j} Rm,j,各个叶子节点的拟合值为:

c m , j = arg ⁡ min ⁡ ∑ x i ∈ R m , j L ( y i , F m − 1 ( x i ) + c ) 上式没有闭式解,一般使用近似值代替 c m , j = ∑ x i ∈ R m , j r m , j ∑ x i ∈ R m , j r m , j ( y i − r m , j ) ( 1 − y i + r m , j ) \begin{align*} c_{m,j}&=\arg\min\sum_{x_{i}\in R_{m,j}}L(y_{i},F_{m-1}(x_{i})+c)\\ &上式没有闭式解,一般使用近似值代替\\ c_{m,j}&=\frac{\sum_{x_i∈R_{m,j}}r_{m,j}}{\sum_{x_i∈R_{m,j}}r_{m,j}(y_i-r_{m,j})(1-y_i+r_{m,j})}\\ \end{align*} cm,jcm,j=argminxiRm,jL(yi,Fm1(xi)+c)上式没有闭式解,一般使用近似值代替=xiRm,jrm,j(yirm,j)(1yi+rm,j)xiRm,jrm,j

(5)更新强学习器

F m ( x ) = F m − 1 ( x ) + l r ∗ ∑ c m , j I ( x i ∈ R m , j ) F_m(x)=F_{m-1}(x)+lr*\sum c_{m,j}I(x_i∈R_{m,j}) Fm(x)=Fm1(x)+lrcm,jI(xiRm,j)
(6)重复3~5共M次,得到最终的强学习器 F M ( x ) F_M(x) FM(x)

F ( x ) = F M ( x ) = F 0 ( x ) + l r ∗ ∑ m = 1 M ∑ j = 1 J c m , j I ( x i ∈ R m , j ) 最终的预测结果为: y ^ i = 1 1 + e − F M ( x ) \begin{align*} F(x)&=F_M(x)=F_0(x)+lr*\sum_{m=1}^M\sum _{j=1}^Jc_{m,j}I(x_i∈R_{m,j})\\\\ &最终的预测结果为:\\\\ \hat y_i&=\frac{1}{1+e^{-F_M(x)}}\\ \end{align*} F(x)y^i=FM(x)=F0(x)+lrm=1Mj=1Jcm,jI(xiRm,j)最终的预测结果为:=1+eFM(x)1

3.3 掉包sklearn实现

# 调取sklearn包
from sklearn.ensemble import GradientBoostingClassifier, GradientBoostingRegressor #sklearn中,线性回归模型在linear_model模块中
from sklearn import tree
# 调取sklearn中自带的数据集
from sklearn.datasets import load_iris #调用鸢尾花分类数据集
from sklearn.datasets import load_boston #调用波士顿房价数据集

X1, y1 = load_iris(return_X_y=True) #获取X,y数据
X2, y2 = load_boston(return_X_y=True) #获取X,y数据

rfc =  GradientBoostingClassifier()#初始化一个随机森林分类模型
rfr = GradientBoostingRegressor()#初始化一个随机森林回归模型

rfc.fit(X1,y1) #fit函数用于训练
rfr.fit(X2,y2)        


详细情况参见:sklearn.ensemble.GradientBoostingClassifier — scikit-learn 1.3.0 documentation

entBoostingClassifier — scikit-learn 1.3.0 documentation](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.GradientBoostingClassifier.html#sklearn.ensemble.GradientBoostingClassifier)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值