转载

梯度提升决策树:GBDT

梯度提升决策树:GBDT

梯度提升决策树:GBDT

PEACEFUL  TIME

Gradient Boosting

Decision Tree

◆  ◆ 

研究GBDT的背景是业务中使用到了该模型,用于做推荐场景,当然这里就引出了GBDT的一个应用场景-回归,他的另外一个应用场景便是分类,接下来我会从以下几个方面去学习和研究GBDT的相关知识,当然我也是学习者,只是把我理解到的整理出来。本文参考了网上各路大神的笔记,在此感谢!

Boosting&Bagging

集成学习方法不是单独的一个机器学习算法,而是通过构建多个机器学习算法来达到一个强学习器。集成学习可以用来进行分类,回归,特征选取和异常点检测等。随机森林算法就是一个典型的集成学习方法,简单的说就是由一个个弱分类器(决策树)来构建一个强分类器,从而达到比较好的分类效果。

那么如何得到单个的学习器,一般有两种方法:

  • 同质(对于一个强学习器而言,所用的单个弱学习器都是一样的,比如说用的都是决策树,或者都是神经网络)

  • 异质(相对于同质而言,对于一个强学习器而言,所用的单个弱学习器不全是一样的,比如说用的决策树和神经网络的组合)

相对异质而言,同质学习期用的最为广泛,我们平时所讨论的集成学习方法指的就是同质个体学习器,同质个体学习器按照个体学习器之间的依赖关系分为串行(有强依赖关系)和并行(不存在关系或者有很弱的依赖关系),而在串行关系中有代表性的就是boosting系列算法,并行关系中具有代表性的就是bagging和随机森林(random forest)

Boosting流程图

梯度提升决策树:GBDT

Bagging流程图

梯度提升决策树:GBDT

上边简单的介绍了集成学习方法和boosting&bagging的区别,那么对于单个学习器采用何种策略才能得到一个强学习器呢?

  • 平均法(加权(个体学习器性能相差较大),简单(性能相近))

  • 投票法(绝对多数(超过半数标记。否则拒绝预测),相对多数,加权投票)

  • 学习法(通过另一个学习器来进行结合,Stacking算法)

Stacking算法:

基本思想:先从初始数据集训练出初级学习器,然后生成一个新数据集用于训练次级学习器。在这个新数据集中,初级学习器的输出被当作样例输入特征,而出事样本的标记仍被当作样例标记。 

注意点:若直接用初级学习器的训练集来产生次级训练集,则过拟合风险会比较大;一般会通过交叉验证等方式,用训练初级学习器未使用的样本来产生次级学习器的训练样本。

Gradient Boosting

Gradient Boosting是一种Boosting的方法,它主要的思想是,每一次建立模型是在之前建立模型损失函数的梯度下降方向。损失函数是评价模型性能(一般为拟合程度+正则项),认为损失函数越小,性能越好。而让损失函数持续下降,就能使得模型不断改性提升性能,其最好的方法就是使损失函数沿着梯度方向下降(讲道理梯度方向上下降最快)。

Gradient Boost是一个框架,里面可以套入很多不同的算法。

分类树&回归树&分类回归树

分类树

三种比较常见的分类决策树分支划分方式包括:ID3, C4.5, CART。

以C4.5分类树为例,C4.5分类树在每次分枝时,是穷举每一个feature的每一个阈值,找到使得按照feature<=阈值,和feature>阈值分成的两个分枝的熵最大的阈值(熵最大的概念可理解成尽可能每个分枝的男女比例都远离1:1),按照该标准分枝得到两个新节点,用同样方法继续分枝直到所有人都被分入性别唯一的叶子节点,或达到预设的终止条件,若最终叶子节点中的性别不唯一,则以多数人的性别作为该叶子节点的性别。

总结:分类树使用信息增益或增益比率来划分节点;每个节点样本的类别情况投票决定测试样本的类别。

回归树

回归树总体流程也是类似,区别在于,回归树的每个节点(不一定是叶子节点)都会得一个预测值,以年龄为例,该预测值等于属于这个节点的所有人年龄的平均值。分枝时穷举每一个feature的每个阈值找最好的分割点,但衡量最好的标准不再是最大熵,而是最小化均方差即(每个人的年龄-预测年龄)^2 的总和 / N。也就是被预测出错的人数越多,错的越离谱,均方差就越大,通过最小化均方差能够找到最可靠的分枝依据。分枝直到每个叶子节点上人的年龄都唯一或者达到预设的终止条件(如叶子个数上限),若最终叶子节点上人的年龄不唯一,则以该节点上所有人的平均年龄做为该叶子节点的预测年龄。

总结:回归树使用最大均方差划分节点;每个节点样本的均值作为测试样本的回归预测值。

分类回归树

Classification And Regression Trees,即既能做分类任务又能做回归任务,CART也是决策树的一种,是一种二分决策树,但是也可以用来做回归,CART同决策树类似,不同于 ID3 与 C4.5 ,分类树采用基尼指数来选择最优的切分特征,而且每次都是二分。至于怎么利用基尼系数进行最优的特征切分,大家可以参考这篇文章的详细介绍 决策树之 CART

损失函数

机器学习中的损失函数有很多,常见的有

  • 0-1损失函数(0-1 loss function)

    梯度提升决策树:GBDT

该损失函数的意义就是,当预测错误时,损失函数值为1,预测正确时,损失函数值为0。该损失函数不考虑预测值和真实值的误差程度,也就是只要预测错误,预测错误差一点和差很多是一样的。

  • 平方损失函数(quadratic loss function)

    梯度提升决策树:GBDT

    取预测差距的平方

  • 绝对值损失函数(absolute loss function)

    梯度提升决策树:GBDT

    取预测值与真实值的差值绝对值,差距不会被平方放大

  • 对数损失函数(logarithmic loss function)

    梯度提升决策树:GBDT

  • 该损失函数用到了极大似然估计的思想。P(Y|X)通俗的解释就是:在当前模型的基础上,对于样本X,其预测值为Y,也就是预测正确的概率。由于概率之间的同时满足需要使用乘法,为了将其转化为加法,我们将其取对数。最后由于是损失函数,所以预测正确的概率越高,其损失值应该是越小,因此再加个负号取个反。

  • 全局损失函数

    梯度提升决策树:GBDT

  • 逻辑回归中的损失函数

    梯度提升决策树:GBDT

GBDT思想

以下部分学习于 GBDT算法原理深入解析 ,原文作者讲的很好,照搬过来,毕竟笔者不是推导数学公式的料,哈哈

梯度提升决策树:GBDT

梯度提升决策树:GBDT

梯度提升决策树:GBDT

GBDT在Scikit-learn中的调用

关于GBDT在Scikit-learn中的实现原文在 [点击查看][3] GBDT在sklearn中导入的包不一样,分类是 from sklearn.ensemble import GradientBoostingClassifier,回归是 from sklearn.ensemble import GradientBoostingRegressor

参数说明

GBDT的参数分为boosting类库参数和弱学习器参数,其中有GBDT的弱学习器为CART,所以弱学习器参数基本为决策树的参数,参考[点击阅读][4]

类库参数

  • loss:损失函数,对于分类模型,有对数似然损失函数”deviance”和指数损失函数”exponential”两者输入选择。默认是对数似然损失函数”deviance”。在原理篇中对这些分类损失函数有详细的介绍。一般来说,推荐使用默认的”deviance”。它对二元分离和多元分类各自都有比较好的优化。而指数损失函数等于把我们带到了Adaboost算法。

  • learning_rate:即每个弱学习器的权重缩减系数νν,也称作步长。

  • n_estimators:就是弱学习器的最大迭代次数,或者说最大的弱学习器的个数。一般来说n_estimators太小,容易欠拟合,n_estimators太大,又容易过拟合,一般选择一个适中的数值。默认是100。在实际调参的过程中,我们常常将n_estimators和下面介绍的参数learning_rate一起考虑。

  • subsample:子采样,取值是[0,1]。注意这里的子采样和随机森林不一样,随机森林使用的是放回抽样,而这里是不放回抽样。如果取值为1,则全部样本都使用,等于没有使用子采样。如果取值小于1,则只有一部分样本会去做GBDT的决策树拟合。选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。推荐在[0.5, 0.8]之间,默认是1.0,即不使用子采样。

  • init:即我们的初始化的时候的弱学习器,如果不输入,则用训练集样本来做样本集的初始化分类回归预测。否则用init参数提供的学习器做初始化分类回归预测。一般用在我们对数据有先验知识,或者之前做过一些拟合的时候,如果没有的话就不用管这个参数了。

  • verbose:默认是0,代表启用详细输出,若为1,代表偶尔输出进度信息

  • warm_start:默认为false

  • random_state:如果int,random_state随机数生成器使用的种子;如果randomstate实例,random_state是随机数发生器;如果没有,随机数生成器使用的np.random的randomstate实例。

  • presort:默认情况下会在密集的数据上使用,默认是在稀疏数据正常排序。设置对true的稀疏数据将会引起错误。

决策树参数

  • max_depth:决策树最大深度

  • criterion:衡量分裂指标的度量方法,支持的是均方误差

  • min_samples_split:内部节点再划分所需最小样本数。这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。 默认是2.如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。

  • min_samples_leaf:叶子节点最少样本数。这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。

  • min_weight_fraction_leaf:叶子节点最小的样本权重和。这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。 默认是0,就是不考虑权重问题。一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。

  • max_features:划分时考虑的最大特征数。可以使用很多种类型的值,默认是”None”,意味着划分时考虑所有的特征数;如果是”log2”意味着划分时最多考虑log2Nlog2N个特征;如果是”sqrt”或者”auto”意味着划分时最多考虑N−−√N个特征。如果是整数,代表考虑的特征绝对数。如果是浮点数,代表考虑特征百分比,即考虑(百分比xN)取整后的特征数。其中N为样本总特征数。一般来说,如果样本特征数不多,比如小于50,我们用默认的”None”就可以了,如果特征数非常多,我们可以灵活使用刚才描述的其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。

  • max_leaf_nodes:最大叶子节点数。通过限制最大叶子节点数,可以防止过拟合,默认是”None”,即不限制最大的叶子节点数。如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制,具体的值可以通过交叉验证得到。

  • min_impurity_split:节点划分最小不纯度。这个值限制了决策树的增长,如果某节点的不纯度(基于基尼系数,均方差)小于这个阈值,则该节点不再生成子节点。即为叶子节点 。一般不推荐改动默认值1e-7。

  • min_impurity_decrease:默认值为0。如果分裂

分类

>>> from sklearn.datasets import make_hastie_10_2
>>> from sklearn.ensemble import GradientBoostingClassifier

>>> X, y = make_hastie_10_2(random_state=0)
>>> X_train, X_test = X[:2000], X[2000:]
>>> y_train, y_test = y[:2000], y[2000:]

>>> clf = GradientBoostingClassifier(n_estimators=100, learning_rate=1.0,...     max_depth=1, random_state=0).fit(X_train, y_train)
>>> clf.score(X_test, y_test)                 
0.913...

回归

>>> import numpy as np
>>> from sklearn.metrics import mean_squared_error
>>> from sklearn.datasets import make_friedman1
>>> from sklearn.ensemble import GradientBoostingRegressor

>>> X, y = make_friedman1(n_samples=1200, random_state=0, noise=1.0)
>>> X_train, X_test = X[:200], X[200:]
>>> y_train, y_test = y[:200], y[200:]
>>> est = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1,...     max_depth=1, random_state=0, loss='ls').fit(X_train, y_train)
>>> mean_squared_error(y_test, est.predict(X_test))    
5.00...

模型评价

from sklearn import cross_validation, metrics
metrics.accuracy_score(y.values, y_pred) # 准确度
metrics.roc_auc_score(y, y_predprob)  # AUC大小

参考资料:

  • 集成学习原理小结

  • Regression Tree 回归树

  • 浅析机器学习中各种损失函数及其含义

梯度提升决策树:GBDT 打开微信扫一扫,加入数据与算法交流大群

▲▲▲▲▲

◆  ◆  ◆   ◆   

长按识别【数据与算法联盟】 微信公众号

梯度提升决策树:GBDT

-完-

原文  http://mp.weixin.qq.com/s/NlsGpLGpE8IPaKzR6WCudw
正文到此结束
Loading...