GBM & GBDT详解

Python013

GBM & GBDT详解,第1张

在理解GBDT之前,我们需要知道什么是GBM,GBM的全称是Gradient Boosting Machines,它是1999年被Jerome Friedman在他的论文中提出来的,从名字中我们可以知道这个算法的关键词:G(Gradient)、B(Boosting)。

为了理解GBM,首先我们需要知道什么是B(Boosting):

Boosting是集成方法中的一种, 集成方法的主要思想是利用一定的手段学习出多个基学习器,而且这多个基学习器要求是弱学习器,然后将多个基学习器进行组合。boosting方法通过分步迭代(stage-wise)的方式来构建模型,每一步迭代构建的弱学习器都是为了弥补已有模型的不足。

G(Gradient)是指用来最小化损失函数的方法,传统的Boosting模型,如Adaboost,最小化损失函数的方式是,每次迭代后,通过更新样本权重分布(分对的样本权重变小,分错的样本权重变大),让后一个基学习器更加关注分错的样本,这样一轮轮的迭代下去,从而达到使损失函数最小化的目标。Adaboost的损失函数是指数损失函数,所以比较好用数学推导的方式去计算每一次迭代时让损失函数达到最小值的最优解,但是其它的损失函数可能不那么容易优化,为了找到一种通用的最优化损失函数的方法,Gradient Boosting被提出来了,Gradient Boosting是指每一步迭代,都是用损失函数的负梯度来拟合弱学习器,以达到使损失函数最小化的目的,GBM 在损失函数的选择上有更大的灵活性。这和梯度下降法的思想是一样的,通过找到使损失函数下降最快的方向,一步一步逼近最小值点,大家可以参考我的另外一篇文章:‘梯度下降和牛顿法’。

我们用 来表示我们的总模型,其中第m步后的模型,可以用上一轮迭代之后的模型 加上本轮学习的基学习器 然后再乘以一个 表示, 和梯度下降中的步长意义是一样的,表示这一步应该走多远:

让我们来看看GBM的训练步骤(以下图片来自维基百科)

GBM中最常用的基学习器是CART回归树,该类GBM算法也叫GBDT。

为什么要选择决策树做基学习器呢,因为决策树有很多优点:

因为基学习器是决策树,所有GBDT在GBM算法的基础上做了一点修改,以更好的发挥决策树的优点。

因为是树模型,所以 可以用 表示,其中 是第m个基决策树的叶子节点数, 是每个叶子节点的值,那么原先的 就可以写成

把 放到求和里面去,就变成了

我们来看看GBDT的训练步骤:

大家可能会有一个疑问,按照上面的步骤,好像(2.1)和(2.2)没什么作用,其实(2.1)和(2.2)是用来确定树结构的,训练后树的每个叶子节点的值通过(2.3)的方式确定,有几个叶子节点,就有几个 值,这样每一步迭代就有多个参数可以调节来进一步改善拟合的质量,使损失函数最小化。

不管是分类问题,还是回归问题,GBDT使用的决策树都是CART回归树,为什么回归树可以解决分类问题呢,因为GBDT基学习器拟合的是负梯度值,负梯度是一个实数,所以基学习器解决的其实是一个回归问题。

回归问题最常见的损失函数有误差平方和、绝对误差等损失函数。

如果损失函数是误差平方和:

此时我们把它叫做 LS_TreeBoost ,具体实现如下:

如果损失函数是绝对误差:

此时我们把它叫做 LAD_TreeBoost ,具体实现如下:

分类问题最常见的损失函数有对数损失函数和指数损失函数。

如果损失函数为对数损失:

其中,

此时我们把它叫做 _TreeBoost ,具体实现如下:

最后应用的时候,还需要通过sigmoid函数,将输出结果转换成概率p,转换公式如下:

上式是作者论文中关于 _TreeBoost 的算法流程图,在2.1中,其实我们无法一眼看出这个负梯度值究竟是什么。

现在我们将 改为 ,损失函数为 ,其中

算法流程如下:

现在我们以分类问题,损失函数为对数损失函数,来推导初始化值、负梯度、叶子节点的值的由来。

已知:

损失函数为 ,其中

1、负梯度值推导

将 值带入 中,得

对上式求导,并取负,则得到我们的负梯度值:

2、初始化值推导

我们知道,初始化值的目标是:

对损失函数求导,并令导数=0,则可求出最优的

导数的运算法则有:

由上可知,每个样本的导数(梯度)为:

加总所有样本的导数,得到总体样本的导数为:

令导数=0,得

又因为对所有的样本,初始化的 都是一样的,所有上式可以写成

从而可得到:

3、叶子节点值

我们知道,每个叶子节点对应的最优的

上式没有闭式解,我们用近似值去替代它,这里用到二阶泰勒展开式去近似:

由于 已知,上面的一阶导、二阶导和 是一个常数

其中:

上式其实就是一个一元二次方程 ,我们知道,一元二次方程取极值的地方就是 ;

当 >0时, 为最小值, 当 <0时, 为最大值;

上式 是一个大于0的值,所以当 时取到最小值

带入上式得:

最终:

在实际应用中,为了防止GBDT过拟合,我们一般有如下处理操作:

4和5都是对每颗树的复杂度进行处理,其他任何控制决策树生长的方法都可以使用。

假设有两组栅格数据,一组代表2019年中国每月降雨量,一组代表2019年中国每月植被叶面积指数(LAI)。想要得到中国月降水量与LAI的相关性分布,那么需要对两组栅格数据对应的栅格点进行逐栅格的相关性分析。

将降水数据导入栅格栈中,这个过程可以理解为将降水数据按时间顺序从上到下堆叠。同理,按相同的时间顺序将LAI数据堆叠。值得一提的是,stack()函数在堆叠栅格数据时是按文件名拼音和数字大小顺序自动堆叠的,具体规则可以亲自尝试。最后,将这两个栅格栈合并成一个。

对相关性分析函数稍作改变。

以上方法是可以推广的,线性回归函数lm()和相关性分析函数cor()的输入都可以是向量,因此只要函数支持向量输入,理论上讲都可以类比上述过程实现。但是如果函数只支持数据框输入,如gbm包中的函数gbm(),那就只能另辟蹊径了。