转自 http://blog.csdn.net/u014568921/article/details/49383379html
另一个很容易理解的文章 :http://www.jianshu.com/p/005a4e6ac775git
更多参考以下github
Gradient Boosting Decision Tree,即梯度提高树,简称GBDT,也叫GBRT(Gradient Boosting Regression Tree),也称为Multiple Additive Regression Tree(MART),阿里貌似叫treelink。面试
首先学习GBDT要有决策树的先验知识。算法
Gradient Boosting Decision Tree,和随机森林(random forest)算法同样,也是经过组合弱学习器来造成一个强学习器。GBDT的发明者是Friedman,至于随机森林则是Friedman的好基友Breiman发明的。不过,GBDT算法中用到的决策树只能是回归树,这是由于该算法的每颗树学的是以前全部树结论之和的残差,这个残差就是一个累加预测值后能获得真实值。经过将每次预测出的结果与目标值的残差做为下一次学习的目标。数据结构
想看英文原文的:app
greedy function approximation :a gradient boosting machine.--GBDT发明者Friedman的文章
框架
Stochastic gradient boosting。仍是Friedman的dom
Boosted Regression (Boosting): An introductory tutorial and a Stata plugin。机器学习
以CART决策树为例,简单介绍一下回归树的构建方法。
下面介绍gradient boost。
Boost是”提高”的意思,通常Boosting算法都是一个迭代的过程,每一次新的训练都是为了改进上一次的结果。咱们熟悉的adaboost算法是boost算法体系中的一类。gradient boost也属于boost算法体系。
Gradient Boost实际上是一个框架,里面能够套入不少不一样的算法。每一次的计算都是为了减小上一次的残差,为了消除残差,咱们能够在残差减小的梯度方向创建一个新的模型,因此说,每个新模型的创建都为了使得以前的模型残差向梯度方向上减小。它用来优化loss function有不少种。
下面是通用的gradient boost框架
要学习的回归树的参数就是每一个节点的分裂属性、最佳切点和节点的预测值。
GBDT算法流程
Friedman的文章greedy function approximation :a gradient boosting machine.中的least-square regression算法以下:
里面yi-Fm-1求得的便是残差,每次就是在这个基础上学习。
目前GBDT有两个不一样的描述版本,网上写GBDT的大都没有说清楚本身说的是哪一个版本,以及不一样版本之间的不一样是什么,读者看不一样的介绍会获得不一样的算法描述,实在让人很头痛。
残差版本把GBDT说成一个残差迭代树,认为每一棵回归树都在学习前N-1棵树的残差,前面所说的主要在描述这一版本。
Gradient版本把GBDT说成一个梯度迭代树,使用梯度降低法求解,认为每一棵回归树在学习前N-1棵树的梯度降低值。
要解决问题仍是阅读Friedman的文章。
读完greedy function approximation :a gradient boosting machine.后,发现4.1-4.4写的是残差版本的GBDT,这一个版本主要用来回归;4.5-4.6写的是Gradient版本,它在残差版本的GBDT版本上作了Logistic变换,Gradient版本主要是用来分类的。
分类问题与回归问题不一样,每棵树的样本的目标就不是一个数值了,而是每一个样本在每一个分类下面都有一个估值Fk(x)。
同逻辑回归同样,假若有K类,每个样本的估计值为F1(x)...Fk(x),对其做logistic变化以后获得属于每一类的几率是P1(x)...pk(x),
则损失函数能够定义为负的log似然:
其中,yk为输入的样本数据的估计值,当一个样本x属于类别k时,yk = 1,不然yk = 0。
将Logistic变换的式子带入损失函数,而且对其求导,能够获得损失函数的梯度:
能够看出对多分类问题,新的一棵树拟合的目标还是残差向量。
用Logistic变换后的算法以下:
对第一棵树,能够初始化每一个样本在每一个分类上的估计值Fk(x)都为0;计算logistic变换pk(x),计算残差向量,做为当前树的回归的目标,回归树的分裂过程仍可采用【左子树样本目标值(残差)和的平方均值+右子树样本目标值(残差)和的平方均值-父结点全部样本目标值(残差)和的平方均值】最大的那个分裂点与分裂特征值等方法;当回归树的叶子节点数目达到要求示,则该树创建完成;对每一个叶子节点,利用落到该叶子节点的全部样本的残差向量,计算增益rjkm;更新每个样本的估计值Fk(x);所以,又能够对估计进行logistic变化,利用样本的目标值计算残差向量,训练第二棵树了。
Shrinkage:即学习率
就是学习率。 通常状况下,越小的学习率,能够越好的逼近预测值,不容易产生过拟合,迭代次数会增长,经验上通常选取0.1左右。
使用缩减训练集
Friedman提出在每次迭代时对base learner从原始训练集中随机抽取一部分(a subsample of the training set drawn at random without replacement)做为本次base learner去拟合的样本集能够提升算法最后的准确率。
限制叶节点中样本的数目
这个在决策树中已经提到过。
剪枝
这个在决策树中已经提到过。
限制每颗树的深度
树的深度通常取的比较小,须要根据实际状况来定。
迭代的次数d
也即最多有多少棵树,树太多可能形成过拟合,即在训练集上表现很好,测试集上表现糟糕;太少则会欠拟合。树的棵树和shrink有关,shrink越小,树会越多。
几个细节提一下
对初始分类器(函数)的选择就能够直接用0,经过平方差LOSS函数求得的残差固然就是样本自己了;也能够选择样本的均值;
一棵树的分裂过程只须要找到找到每一个结点的分裂的特征id与特征值,而寻找的方法能够是平均最小均方差,也能够是使得(左子树样本目标值和的平方均值+右子树样本目标值和的平方均值-父结点全部样本目标值和的平方均值)最大的那个分裂点与分裂特征值等等方法;从而将样本分到左右子树中,继续上面过程;
注意样本的估计值Fk(x)是前面全部树的估值之和,所以,计算残差时,用样本的目标值减去Fk(x)就能够获得残差了
http://www.cnblogs.com/LeftNotEasy/archive/2011/03/07/random-forest-and-gbdt.html这篇文章关于分类讲得比较好,借鉴了他写的一些,例子也很好,你们能够看看。
https://github.com/MLWave/Kaggle-Ensemble-Guide