GBDT原理详解
从提升树出发,——》回归提升树、二元分类、多元分类三个GBDT常见算法。
- 提升树
- 梯度提升树
- 回归提升树
- 二元分类
- 多元分类
- 面经
提升树
在说GBDT之前,先说说提升树(boosting tree)。说到提升(boosting),总是绕不过AdaBoost。
AdaBoost是利用前一轮迭代的误差率来更新训练集的权重,校正前一轮迭代被错误分类的样本,通俗一点的理解就是将重心放在分错的样本上。提升树也是boosting家族的成员,意味着提升树也采用加法模型(基学习器线性组合)和前向分步算法。
下面一个一个进行解释,提升树的基学习器是什么,加法模型和前向分步算法又是怎么用的。
提升树通常以决策树作为基学习器,对分类问题决策树是二叉分类树,回归问题就是二叉回归树。
加法模型,就是说提升树可以表示为以下形式:这里我们约定 $ T(x;Θ_m ) $表示第m棵决策树;$ Θ_m $表示决策树的参数;$ M $为树的个数。强分类器$f_M (x)$可以由多个弱分类器$T(x;Θ_m )$线性相加而成。
$$f_M (x)=\sum_{m=1}^MT(x;Θ_m ) $$
提升树的前向分步算法。第m步的模型可以写成:
$$f_m (x)=f_{m-1} (x)+ T(x;Θ_m )$$
然后得到损失函数
$$L(f_m (x),y)=L(f_{m-1} (x)+ T(x;Θ_m ),y)$$
迭代的目的是构建$T(x;Θ_m )$,使得本轮损失$L(f_m (x),y)$最小。思想其实并不复杂,但是问题也很明显,对于不同的任务会有不同的损失函数,当损失函数是平方损失和指数损失函数时,每一步的优化还是简单的。但是对于一般损失函数而言,每一步的优化并不容易。
梯度提升树
下面关于GBDT的理解来自论文greedy function approximation: a gradient boosting machine
- 损失函数的数值优化可以看成是在函数空间,而不是在参数空间。
- 损失函数$L(y,F)$包含平方损失$(y-F)^2$,绝对值损失$|y-F|$用于回归问题,负二项对数似然$log(1+e^{-2yF} )$,y∈{-1,1}用于分类。
- 关注点是预测函数的加性扩展。
最关键的点在于损失函数的数值优化可以看成是在函数空间而不是参数空间。怎么理解呢?
首先,我们已经知道强分类器是由多个弱分类器线性相加而成,那么可以写成如下形式:
$$F(x;\{β_m,a_m \}_1^M )=\sum_{m=1}^Mβ_m h(x;a_m )$$
这里的$h(x;a_m )$指代回归树,例如CART。$a_m$是模型参数,这里指代每个节点的分裂特征(变量),最佳分割点,节点的预测值。$M$就是有多少个弱分类器。
然后,我们来回顾一下参数空间的数值优化。假设预测函数为$F(x;P)$,那么损失函数就可以写成:
$$ ϕ(P)=L(y,F(x,P))$$
优化以后得到的参数最优解为:
$$P^~=argmin_P ϕ(P) $$
回想一下SGD(随机梯度下降)的优化方式,从山顶上选择梯度下降最快的方向挪动最优步长。我们是不是可以把最优参数表达成这个形式?
$$P^~=\sum_{m=0}^Mp_m $$
$$p_m=-ρ_m g_m$$
从初始值$p_0$开始,$m$对应每一步更新迭代,负梯度$-g_m$就是最速下降方向,$ρ_m$就是在这个最速下降方向上进行线搜索得到的最优步长。
好了,现在我们说说函数空间的优化方法。
将预测函数$F(x)$对应参数$P$,最优解变成了:
$$F(x)=\sum_{m=0}^Mf_m (x)$$
相当于在函数空间上作梯度下降。每一步梯度下降:
$$f_m(x)=-ρ_m g_m(x)$$
$$g_m (x)=[\frac{-∂ϕ(F(x))}{∂F(x)} ]_{F(x)=F_{m-1} (x) }$$
$$F_{m-1}(x)=\sum_{i=0}^{m-1}f_i(x)$$
现在把这个思想代入到gradient boosting,我们之前已经得到预测函数为:
$$F(x;\{β_m,a_m \}_1^M )=\sum_{m=1}^Mβ_m h(x;a_m ) $$
需要做的事情是得到预测函数的最优解,就是:
$$\{\textbf{β}_m, \textbf{a}_m \}_1^M= argmin_{\{β_m,a_m\}_1^M} L(y,\sum_{m=1}^Mβ_m h(x;a_m ))= argmin_{β_m,a_m} L(y,F_{m-1} (x)+β_mh_m (x;a_m))$$
已知最速梯度下降方向为$g_m (x)=[\frac{-∂ϕ(F(x))}{∂F(x) }]_{F(x)=F_{m-1} (x) }$,每一个$h_m (x;a_m)$都建立在最速梯度下降的方向,我们可以得到:
$$\textbf{a}_m=argmin_{β_m,a_m} [-g_m (x)-β_mh_m (x;a_m) ]^2$$
可以认为是用$h_m (x;a)$去拟合伪标签$\tilde{y}=-g_m (x)$。这里为什么用最小二乘,我的理解是GBDT构造的树全是回归树,因此用最小二乘。
然后进行线搜索确定最优步长$ρ_m$:
$$\textbf{ρ}_m= argmin_{ρ_m} L(y,F_{m-1}(x)+ρ_mh_m (x;\textbf{a}_m))$$
$$F_m (x)=F_{m-1} (x)+ \textbf{ρ}_m h_m (x;\textbf{a}_m) $$
ok,现在来整理整个算法流程:
- 初始化:$F_0 (x)=argmix_ρ\sum_{i=1}^NL(y_i,ρ)$ ,$N$表示样本量
- For $m=1$ to $M$ do:end for
- $\tilde{y}=-[\frac{∂ϕ(F(x))}{∂F(x)} ]_{F(x)=F_(m-1) (x) },i=1,2,……,N$
- $\textbf{a}_m=argmin_{β,a}\sum_{i=1}^N [\tilde{y}-βh_m (x_i;a) ]^2$
- $\textbf{ρ}_m= argmin_ρ\sum_{i=1}^N L(y_i,F_{m-1} (x_i)+ρh_m (x_i;\textbf{a}_m ))$
- $F_m (x)=F_{m-1} (x)+\textbf{ρ}_m h_m (x;\textbf{a}_m)$
回归提升树
当基学习器$h(x;a)$是一个包含J个节点的回归树时,可以写成:
$$h(x;a)=h(x;\{c_j,R_j\}_1^J)=\sum_{j=1}^Jc_jI(X∈R_j)$$
写完公式发现原来可以写的这么复杂,简单点说就是,对于回归树$h$,如果$x$被归到某个叶子节点$R_j$,那么$x$在这个$h$中得到的预测值就是叶子节点$R_j$的值$c_j$。一般用叶子节点上 $\{x_i∈R_j \}_1^J$的$\{\tilde{y}_i\}_1^J$平均值近似节点$R_j$的值
$$c_j=ave_{x_i∈R_j}\tilde{y}_i $$
$\{R_j\}_1^J$是不相交的区域,集合覆盖预测值的空间。$\{c_j\}_1^J$可以认为是回归树$h$的系数。什么意思?我们回想一下线性回归,预测函数是$θ^T x$,这个$θ$就是模型系数。同样的,也可以这么理解$\{c_j\}_1^J$,是回归树$h$的系数。
ok,现在我们已经得到了回归提升树的预测函数:
$$F_m (x)=F_{m-1} (x)+ρ_m \sum_{j=1}^Jc_{m,j}I(x∈R_j)$$
令$γ_{m,j}=ρ_mc_{m,j}$,这个值是叶子节点的最理想的常数更新值,也可以认为兼顾了下降方向和下降步长。
综上,整理一下回归提升树的整个算法流程:
- 输入:训练数据集$T=\{(x_1,y_1),(x_2,y_2),……,(x_N,y_N)\}$,迭代次数$M$
- 1. 初始化:$F_0 (x)=argmin_ρ\sum_{i=1}^NL(y,ρ)$ ,$N$表示样本量
- 2. For $m=1$ to $M$ do:
- (a) 计算损失函数在当前模型$F_{m-1} (x)$的负梯度值:
$$\tilde{y}=-[\frac{∂ϕ(F(x))}{∂F(x)}]_{F(x)=F_{m-1}(x) }=y_i-F_{m-1}(x_i),i=1,2,……,N$$
- (b) 根据$\tilde{y}_i$学习得到了第$m$棵回归树,对应的叶节点区域为$\{R_j \}_1^J$
- (c) $γ_{m,j}=argmin_γ\sum_{x_i∈R_{m,j}}L(y_i,F_{m-1}(x_i)+γ)$
- (d) 得到本轮最佳拟合决策树为:
$$h_m(x;a)=\sum_{j=1}^Jγ_{m,j}I(x∈R_{m,j})$$
- (e) 得到本次迭代得到的强学习器:
$$F_m(x)=F_{m-1}(x)+\sum_{j=1}^Jγ_{m,j}I(x∈R_{m,j})$$
- 3.结束迭代之后的强学习器为:
$$F_M(x)=\sum_{m=1}^M\sum_{j=1}^Jγ_{m,j}I(x∈R_{m,j})$$
当当当~看到第3点,我们发现损失函数在当前模型$F_{m-1}(x)$的负梯度值刚刚好是$y-F_{m-1}(x)$,也就是我们常说的残差!看到这里有没有很激动?这不就是我们常说的GBDT是在拟合前几轮迭代的残差吗?
下面给出证明:
令当前的预测函数模型为$F_{m-1}(x)$,下一棵要学习的回归树为$h_m (x;a)$,则下一步要学习的预测函数为:
$$F_m(x)=F_{m-1}(x)+h_m(x;a_m)$$
回归提升树的损失函数为平方损失:
$$Loss=L(F_m(x),y)=\frac{1}{2}(F_m(x)-y)^2$$
对$F_m (x)$求关于$a_m$的偏导:
$$\frac{∂Loss}{∂a_m}=(F_m(x)-y)=F_{m-1}(x)+h_m(x;a_m)-y$$
我们要使经验风险极小化,令偏导为0:
$$h_m(x;a_m)=y-F_{m-1}(x)$$
也就是说,构建的回归树要去拟合前面的残差,得证。可以这么理解,GBDT是在函数空间的梯度下降求最优值,当损失函数为平方损失时,恰好去拟合了残差。
下面给一个简单的例子方便理解,现在要通过购物金额和上网时长来预测年龄。假设有5个训练样本,标签分别14,17,13,25,27。第m轮迭代,通过前几轮的残差构建决策树,得到预测函数$F_m (x)$的预测年龄分别为16,15,12,19,29,计算残差-2,2,1,6,-2。第m+1轮迭代,就去学习这个残差,通俗一点说就是以残差作为第i+1轮迭代构建决策树的标签。
二元分类
我们使用负二项对数似然作为损失函数:
$$L(y,F)=log(1+exp(-2yF)),y∈\{1,1\}$$
其中,$F(x)=\frac{1}{2}log[\frac{P(y=1|x)}{P(y=-1|x)}]$
看这个公式有没有很熟悉?是的,这个负二项对数似然可以推到逻辑回归的损失函数。
我们知道逻辑回归的预测函数为:
$$P(y=1|x)=\frac{1}{1+exp(-θ^Tx)},y∈\{0,1\}$$
我们知道这里的负样本y=-1对应于逻辑回归里的负样本y=0,所以有:
$$F(x)=\frac{1}{2}log[\frac{P(y=1|x)}{P(y=-1|x)}]=\frac{1}{2}log[\frac{P(y=1|x)}{P(y=0|x)}]=\frac{1}{2}θ^Tx$$
将上式代入$L(y,F)$,可得$L(y,F)=log(1+exp(-2yF))=log(1+exp(-yθ^Tx)),y∈\{-1,1\}$
当y=1时,$L(y,F)= log(1+exp(-θ^T x))=y log(1+exp(-θ^T x) )=ylog(P(y=1|x))$
当y=-1时,$L(y,F)=log(1+exp(θ^T x) )=log(1-P(y=1|x))$
令$y$←0,$L(y,F)=(1-y)log(1-P(y=1|x))$
结合在一起,可以写成:
$$L(y,F)=ylog(P(y=1|x))+(1-y)log(1-P(y=1|x)),y∈\{0,1\}$$
与逻辑回归损失函数一致,得证。
预测函数$F_{m-1} (x)$的当前负梯度值,也可以说是伪响应$\tilde{y}$为:
$$\tilde{y}=-[\frac{∂L(F(x),y)}{∂F(x)}]_{F(x)=F_{m-1}(x)}=\frac{2y}{1+exp(2yF_{m-1}(x))}$$
我们仍然将回归树作为基学习器,进行线搜索得到最优叶子节点值:
$$γ_{m,j}=argmin_y\sum_{x∈R_{m,j}}log(1+(-2y(F_{m-1}(x)+γ)))$$
一看这个公式就知道计算量不是一般的大,我们用[Newton-Raphson近似][2],得到:
$$γ_{m,j}=\frac{\sum_{x∈R_{m,j}}\tilde{y}_i}{\sum_{x∈R_{m,j}}|\tilde{y}_i|(2-|\tilde{y}|)}$$
总结一下算法流程如下:
- 1. 初始化:$F_0 (x)=argmix_ρ\sum_{i=1}^NL(y,ρ)$ ,$N$表示样本量
- 2. For $m=1$ to $M$ do:3. end For
- (a) $\tilde{y}_i=\frac{2y_i}{1+exp(2y_iF_{m-1}(x_i))},i=1,2,……,N$
- (b) 根据$\tilde{y}_i$学习得到了第m棵回归树,对应的叶节点区域为$\{R_j\}_1^J$
- (c) $γ_{m,j}=\frac{\sum_{x∈R_{m,j}}\tilde{y}_i}{\sum_{x∈R_{m,j}}|\tilde{y}_i|(2-|\tilde{y_i}|)}$
- (d) $F_m (x)=F_{m-1} (x)+\sum_{j=1}^Jγ_{m,j} I(x∈R_{m,j})$
最后,我们得到了预测函数$F_M(x)$,用来进行概率估计:
$$P(y=1|x)=p=\frac{e^{2F(x)}}{1+e^{2F(x)}}=\frac{1}{1+e^{-2F(x)}}$$
$$P(y=-1|x)=1-p=\frac{1}{1+e^{2F(x)}}$$
有了概率之后,我们可以对样本进行分类。
多元分类
我们使用多分类log损失作为损失函数:
$$L(y,F)=-\sum_{k=1}^{K}y_klogp_k(x)$$
对应的概率$p_k(x)$为(就是softmax):
$$p_k (x)=\frac{e^{F_k (x)}}{\sum_{l=1}^Ke^{F_l (x)}}$$
对于多分类问题,在构建基学习器时,我们要为每个类别k创建一棵回归树$F_k (x),k=1,2,……,K$
$$\tilde{y}_{i,k}=y_{i,k}-p_{k,m-1} (x_i)$$
因此,每次迭代m,以概率角度来计算当前残差。
叶子节点值近似为:
$$γ_{m,j}=\frac{K-1}{K}\frac{\sum_{x∈R_{m,j}}\tilde{y}_i}{\sum_{x∈R_{m,j}}|\tilde{y}_i|(2-|\tilde{y}|)}$$
面经
- GBDT为什么是在拟合前面几轮的残差?请公式推导。
- SVM为什么要比GBDT好?(这个问题有点奇怪,但是面试官真的是这么问的(微笑脸),因为我简历里写了用SVM做分类,面试官就问为什么不用GBDT,SVM比GBDT好在哪里?……)这个问题我至今不知道答案,请大神赐教。
- GBDT和LR的差别。(这个问题可以推广的,和AdaBoost、RF、XgBoost,etc的差别)
- 在你所知的算法中,哪个抗噪能力最强?哪个对采样不敏感?
作者 Scorpio.Lu
转载请注明出处!
GBDT原理详解的更多相关文章
- XGBoost,GBDT原理详解,与lightgbm比较
xgb原理: https://www.jianshu.com/p/7467e616f227 https://blog.csdn.net/a819825294/article/details/51206 ...
- I2C 基础原理详解
今天来学习下I2C通信~ I2C(Inter-Intergrated Circuit)指的是 IC(Intergrated Circuit)之间的(Inter) 通信方式.如上图所以有很多的周边设备都 ...
- Zigbee组网原理详解
Zigbee组网原理详解 来源:互联网 作者:佚名2015年08月13日 15:57 [导读] 组建一个完整的zigbee网状网络包括两个步骤:网络初始化.节点加入网络.其中节点加入网络又包括两个 ...
- 块级格式化上下文(block formatting context)、浮动和绝对定位的工作原理详解
CSS的可视化格式模型中具有一个非常重要地位的概念——定位方案.定位方案用以控制元素的布局,在CSS2.1中,有三种定位方案——普通流.浮动和绝对定位: 普通流:元素按照先后位置自上而下布局,inli ...
- SSL/TLS 原理详解
本文大部分整理自网络,相关文章请见文后参考. SSL/TLS作为一种互联网安全加密技术,原理较为复杂,枯燥而无味,我也是试图理解之后重新整理,尽量做到层次清晰.正文开始. 1. SSL/TLS概览 1 ...
- 锁之“轻量级锁”原理详解(Lightweight Locking)
大家知道,Java的多线程安全是基于Lock机制实现的,而Lock的性能往往不如人意. 原因是,monitorenter与monitorexit这两个控制多线程同步的bytecode原语,是JVM依赖 ...
- [转]js中几种实用的跨域方法原理详解
转自:js中几种实用的跨域方法原理详解 - 无双 - 博客园 // // 这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同 ...
- 节点地址的函数list_entry()原理详解
本节中,我们继续讲解,在linux2.4内核下,如果通过一些列函数从路径名找到目标节点. 3.3.1)接下来查看chached_lookup()的代码(namei.c) [path_walk()> ...
- WebActivator的实现原理详解
WebActivator的实现原理详解 文章内容 上篇文章,我们分析如何动态注册HttpModule的实现,本篇我们来分析一下通过上篇代码原理实现的WebActivator类库,WebActivato ...
随机推荐
- nginx下目录浏览及其验证功能、版本隐藏等配置记录
工作中常常有写不能有网页下载东西的需求,在Apache下搭建完成后直接导入文件即可达到下载/显示文件的效果;而Nginx的目录列表功能默认是关闭的,如果需要打开Nginx的目录列表功能,需要手动配置, ...
- Jenkins新建项目中源码管理Repository URL使用Git报错:Failed to connect to repository : Command "git ls-remote -h......
之前部署了Gitlab+Gerrit+Jenkins持续集成环境,但在Jenkins中新建项目的源码管理"Repository URL"中添加git地址环节出现了问题,信息为&qu ...
- 四则运算coding
https://coding.net/u/ztf1641429293/p/sizeyunshuan/git/blob/master/Sizenyunsuan.java
- Echarts中graph类型的运用求教
以下是百度Echarts官网上关系图的源码,但是这个关系图的node节点和edge都是静态文件里规定好的,我现在想动态实现,点击其中一个节点A然后新产生一个新节点B,并且有A和B之间的edge,就类似 ...
- 读《移山之道-VSTS软件开发指南》
首先,我选择<移山之道>有几个原因.第一,书的名字给我一种新鲜感,而不是像另外两本书那么平常:第二,作者邹欣是老师推荐的,看一看他的书或许能让我发现老师对他推崇备至的原因,而实际上,读完这 ...
- 个人博客作业_week14
M1/M2阶段总结 我在M1阶段负责后端代码的开发,以及协助PM,在M2阶段负责PM,在为期将近一学期的团队软件开发过程中,我深刻体会到了团队协作的重要性,以及合理分配任务的重要性,没有一个好的时间规 ...
- first time to use github
first time to use github and feeling good. 学习软件工程,老师要求我们用这个软件管理自己的代码,网站是全英的,软件也简单易用,方便 https://githu ...
- C++中struct 和 class的区别
首先,C++中类的定义,从狭义上理解,就是我们使用的class类型.从广义上,类就是定义了一个新的类型和新的作用域,它具有成员函数和成员数据. 而对广义类定义的实现分为两种,一种是使用struct实现 ...
- [福大软工] Z班——Alpha现场答辩情况汇总
Alpha现场答辩 小组互评(文字版) 各组对于 麻瓜制造者 的评价与建议 队伍名 评价与建议 *** 界面较友好,安全性不足,功能基本完整.希望能留下卖家的联系方式而不是在APP上直接联系,APP上 ...
- Cmder 常用配置
windows 系统的 cmd 命令窗口不是很好用,可以试试 Cmder 工具包. 1.在运行框中快速启动 Cmder 将 cmder.exe 文件所在目录加载环境变量 PATH 中. 2.把 cms ...