GBDT

GBDT(Gradient Boosting Decision Tree)是一种基于迭代所构造的决策树算法,GBDT由很多回归树构成,每一棵新回归树f(x)都是建立在之前迭代的强分类器的损失函数梯度降低的方向。

GBDT主要由三个概念组成:Regression Decistion Tree、Gradient Boosting与Shrinkage. 

1.GBDT之Regression Decistion Tree,即回归决策树。  

GBDT中的所有决策树都是回归树,而非分类树。这是因为该算法的每颗树学的是之前所有树结论之和的残差,这个残差就是一个累加预测值后能得到真实值。通过将每次预测出的结果与目标值的残差作为下一次学习的目标。基于回归树所得到的数值进行加减是有意义的,这是区别于分类树的一个显著特征(毕竟男+女=是男是女?,这样的运算是毫无道理的)。 

详细参考[决策树的构建](http://blog.csdn.net/suv1234/article/details/72584974) 

2.GBDT之gradient boost——梯度提升  

Gradient Boost其实是一个框架而非一个具体的算法,其基本思想为:沿着梯度方向,构造一系列的弱分类器函数,并以一定权重组合起来,形成最终决策的强分类器。 每一次的计算都是为了减少上一次的残差,为了消除残差,我们可以在残差减少的梯度方向建立一个新的模型,所以说,每一个新模型的建立都为了使得之前的模型残差向梯度方向上减少。它用来优化loss function有很多种。

GBDT常用损失函数
对于分类算法,其损失函数一般有对数损失函数和指数损失函数两种:
a) 如果是指数损失函数,则损失函数表达式为
L(y,f(x))=exp(−yf(x))
b) 如果是对数损失函数,分为二元分类和多元分类两种。

二分类:L(y,f(x))=log(1+exp(−yf(x)))

对于回归算法,常用损失函数有如下4种:
a)均方差,这个是最常见的回归损失函数了
L(y,f(x))=(y−f(x))2
b)绝对损失,这个损失函数也很常见
L(y,f(x))=|y−f(x)|
对应负梯度误差为:
sign(yi−f(xi))
c)Huber损失,它是均方差和绝对损失的折衷产物,对于远离中心的异常点,采用绝对损失,而中心附近的点采用均方差。这个界限一般用分位数点度量。
对于Huber损失,主要用于健壮回归,也就是减少异常点对损失函数的影响。

下面是通用的gradient boost框架



 

要学习的回归树的参数就是每个节点的分裂属性、最佳切点和节点的预测值。





GBDT算法流程



least-square regression算法如下:



求得的即是残差,每次就是在这个基础上学习。

目前GBDT有两个不同的描述版本

残差版本把GBDT说成一个残差迭代树,认为每一棵回归树都在学习前N-1棵树的残差,前面所说的主要在描述这一版本。
Gradient版本把GBDT说成一个梯度迭代树,使用梯度下降法求解,认为每一棵回归树在学习前N-1棵树的梯度下降值。

这两种理解角度从总体流程和输入输出上没有区别的,它们都是迭代回归树,都是累加每棵树结果作为最终结果,每棵树都在学习前面树尚存的不足。而不同之处就在于每一步迭代时的求解方法的不同,前者使用残差(残差是全局最优值),后者使用梯度(梯度是局部最优方向),简单一点来讲就是前者每一步都在试图向最终结果的方向优化,后者则每一步试图让当前结果更好一点。

看起来前者更科学一点,毕竟有绝对最优方向不学,为什么舍近求远去估计一个局部最优方向呢?原因在于灵活性。前者最大问题是,由于它依赖残差,损失函数一般固定为反映残差的均方差,因此很难处理纯回归问题之外的问题。而后者求解方法为梯度下降,只要可求导的损失函数都可以使用。

残差版本的GBDT主要用来回归;Gradient版本在残差版本上做了Logistic变换,Gradient版本主要是用来分类的。

分类问题与回归问题不同,每棵树的样本的目标就不是一个数值了,而是每个样本在每个分类下面都有一个估值Fk(x)。

这里要注意的是这里的多分类采用的是one——hot编码,也就是说若果有5个类别,Xk属于第一类的话,有(1,0,0,0,0)。这样就把标称值转化为了有意义的数值型,就可以进行回归树的建立了。回归树的分裂过程仍可采用【左子树样本目标值(残差)和的平方均值+右子树样本目标值(残差)和的平方均值-父结点所有样本目标值(残差)和的平方均值】最大的那个分裂点与分裂特征值等方法;当回归树的叶子节点数目达到要求示,则该树建立完成;
同逻辑回归一样,假如有K类,每一个样本的估计值为F1(x)...Fk(x),对其作logistic变化之后得到属于每一类的概率是P1(x)...pk(x),



则损失函数可以定义为负的log似然:



其中,yk为输入的样本数据的估计值,当一个样本x属于类别k时,yk = 1,否则yk = 0。

将Logistic变换的式子带入损失函数,并且对其求导,可以得到损失函数的梯度:




可以看出对多分类问题,新的一棵树拟合的目标仍是残差向量。

用Logistic变换后的算法如下:


0. 表示给定一个初始值

1. 表示建立M棵决策树(迭代M次)

2. 表示对函数估计值F(x)进行Logistic变换

3. 表示对于K个分类进行下面的操作(其实这个for循环也可以理解为向量的操作,每一个样本点xi都对应了K种可能的分类yi,所以yi, F(xi), p(xi)都是一个K维的向量,这样或许容易理解一点)

4. 表示求得残差减少的负梯度方向

5. 表示根据每一个样本点x,与其残差减少的梯度方向,得到一棵由J个叶子节点组成的决策树

6. 当决策树建立完成后,通过这个公式,可以得到每一个叶子节点的增益(这个增益在预测的时候用的)

每个增益的组成其实也是一个K维的向量,表示如果在决策树预测的过程中,如果某一个样本点掉入了这个叶子节点,则其对应的K个分类的值是多少。比如说,GBDT得到了三棵决策树,一个样本点在预测的时候,也会掉入3个叶子节点上,其增益分别为(假设为3分类的问题):(0.5, 0.8, 0.1), (0.2, 0.6, 0.3), (0.4, 0.3, 0.3)

7. 的意思为,将当前得到的决策树与之前的那些决策树合并起来,作为新的一个模型(跟6中所举的例子差不多)


对第一棵树,可以初始化每个样本在每个分类上的估计值Fk(x)都为0;计算logistic变换pk(x),计算残差向量,作为当前树的回归的目标,对每个叶子节点,利用落到该叶子节点的所有样本的残差向量,计算增益rjkm;更新每一个样本的估计值Fk(x);因此,又可以对估计进行logistic变化,利用样本的目标值计算残差向量,训练第二棵树了。

假设输入数据x可能属于5个分类(分别为1,2,3,4,5),训练数据中,x属于类别3,则y = (0, 0, 1, 0, 0),假设模型估计得到的F(x) = (0, 0.3, 0.6, 0, 0),则经过Logistic变换后的数据p(x) = (0.16,0.21,0.29,0.16,0.16),y – p得到梯度g:(-0.16, -0.21, 0.71, -0.16, -0.16)。


3. 正则化regularization

Shrinkage:即学习率



就是学习率。 一般情况下,越小的学习率,可以越好的逼近预测值,不容易产生过拟合,迭代次数会增加,经验上一般选取0.1左右。

第二种正则化的方式是通过子采样比例(subsample)
(a subsample of the training set drawn at random without replacement)作为本次base
learner去拟合的样本集可以提高算法最后的准确率。

GBDT里的做法是在每一轮建树时,样本是从训练集合中无放回随机抽样,XGBoost和Sklearn的实现均借鉴了随机森林,除了有样本层次上的采样,也有特征采样。也就是说建树的时候只从随机选取的一些特征列寻找最优分裂。 下面是Sklearn里的相关参数设置的片段

def __init__(self, ..., subsample=1.0, max_features=None,...):
    """



第三种是对于弱学习器即CART回归树进行

1、正则化剪枝。
2、限制叶节点中样本的数目。
3、限制每颗树的深度。树的深度一般取的比较小,需要根据实际情况来定。
4、迭代的次数d。也即最多有多少棵树,树太多可能造成过拟合,即在训练集上表现很好,测试集上表现糟糕;太少则会欠拟合。树的棵树和shrink有关,shrink越小,树会越多。



  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值