Spark2.3 源码解析 之 梯度提升树 gradient boosting tree
一、理论
理论部分源自 Machine Learning-A Probabilistic Perspective(MLAPP)和 Elements of Statistical Machine Learning(ESML)1、boosting
boosting是一种greedy算法,书中也称作一种adaptive basis-function model (ABM),形式如下:

2、gradient boosting
gradient boosting的伪代码如下(摘自MLAPP):
梯度提升(gradient boosting)是一种改进的boosting方法。boosting算法的目标是让模型输出逼近真实值,即最小化Loss=L(y,f)。那么boosting每一步的目标就是:通过 弱学习器φm 来改进f,使得loss逐步减少。
那么问题就来了:f 应该向什么方向改进呢?即φm取什么值才能让loss下降最快呢?这就离梯度gradient很近了,因为loss下降最快的方向就是对f的一阶导数 即梯度gradient。因此根据gradient梯度来更新f就是gradient boosting的目的。
那么具体怎么更新呢:每次根据gradient(伪代码中 r )拟合一个弱学习器φ,并累加给f(乘以学习速率)。即gradient boosting模型中每个弱学习器都是对gradient的拟合。
(1)损失函数定义loss
根据任务类型不同,损失函数Loss的定义也不同,具体见下图(MLAPP 556页 table16.1):

(2)Logloss推导
平方损失和绝对值损失不详细介绍,Expoential指数损失过于关注错误样本,因此受到错误样本的干扰很大(比如非常离谱的数据),这里也不做介绍。
此处主要讨论gradient boosting的Logloss如何得来的,不啰嗦,直接赋上ESML的介绍:

其中,根据p(x)推导出损失函数 l(Y,p(x))不难,根据p(x)也可以推导出f(x)=1/2的log-odds
但问题是:p(x)如何而来?为什么不是LR一样的sigmoid函数?
注意:这里的Loss是 y与f之间的loss,其中导数也是对f求导(因为每个f是一个弱分类器,目的是f拟合梯度gradient),这里的loss和gradient都与x无关
(3)spark中损失函数
在spark采用的损失函数为: