决策树、随机森林、bagging、boosting、Adaboost、GBDT、XGBoost总结

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

决策树、随机森林、bagging、boosting、Adaboost、GBDT、XGBoost总结作者:ChrisCao
⼀. 决策树
决策树是⼀个有监督分类模型,本质是选择⼀个最⼤信息增益的特征值进⾏输的分割,直到达
到结束条件或叶⼦节点纯度达到阈值。

下图是决策树的⼀个⽰例图:
根据分割指标和分割⽅法,可分为:ID3、C4.5、CART算法。

1.ID3算法:以信息增益为准则来选择最优划分属性
信息增益的计算是基于信息熵(度量样本集合纯度的指标)
信息熵越⼩,数据集的纯度越⼤
假设基于数据集上建⽴决策树,数据有个类别:
公式(1)中:
表⽰第K类样本的总数占数据集D样本总数的⽐例。

公式(2)表⽰是以特征A作为分割的属性,得到的信息熵:Di表⽰的是以属性A为划分,分成n个
分⽀,第i个分⽀的节点集合。

因此,该公式求得的是以属性A为划分,n个分⽀的信息熵总和。

公式(3)是以A为属性划分前和划分后的信息熵差值,也就是信息增益,越⼤越好。

假设每个记录有⼀个属性'ID',若按照ID进⾏分割的话,在这个属性上,能够取得的特征值是样本
数,特征数⽬太多,⽆论以哪⼀个ID进⾏划分,叶⼦节点的值只会有⼀个,纯度很⼤,得到的
信息增益很⼤,这样划分出来的决策树没有意义,即,ID3偏向于取值较多的属性进⾏分割,存
在⼀定的偏好。

为减少这⼀影响,有学者提出了C4.5算法。

2.C4.5基于信息增益率准则选择最有分割属性的算法
信息增益率通过引⼊⼀个被称为分裂信息(Split information)的惩罚项来惩罚取值较多的属性:
,
其中,IV(a)是由属性A的特征值个数决定的,个数越多,IV值越⼤,信息增益率越⼩,这样就可
以避免模型偏好特征值多的属性,如果简单按这个规则分割,模型⼜会偏好特征值少的特征,
因此C4.5决策树先从候选划分属性中找出信息增益⾼于平均⽔平的属性,在从中选择增益率最
⾼的。

对于连续值属性来说,可取值数⽬不再有限,因此可以采⽤离散化技术(如⼆分法)进⾏处
理。

将属性值从⼩到⼤排序,然后选择中间值作为分割点,数值⽐它⼩的点被划分到左⼦树,
数值不⼩于它的点被分到右⼦树,计算分割的信息增益率,选择信息增益率最⼤的属性值进⾏
分割。

3.CART:以基尼系数为准则选择最优划分属性,可⽤于分类和回归
CART是⼀棵⼆叉树,采⽤⼆元切分法,每次把数据分成两份,分别进⼊左⼦树、右⼦树。

并且
每个⾮叶⼦节点都有两个孩⼦,所以CART的叶⼦节点⽐⾮叶⼦节点多⼀。

相⽐于ID3和
C4.5,CART的应⽤要多⼀些,既可以⽤于分类也可以⽤于回归。

CART分类时,选择基尼指数
(Gini)为最好的分类特征,gini描述的是纯度,与信息熵含义类似,CART中每次迭代都会降
低基尼系数。

Gini(D)反映了数据集D的纯度,值越⼩,纯度越⾼。

我们在候选集合中选择使得划分后基尼指
数最⼩的属性作为最优化分属性。

分类树和回归树
先说分类树,ID3、C4.5在每⼀次分⽀时,是穷举每⼀个特征属性的每⼀个阈值,找到使得按照
特征值<=阈值,和特征值>阈值分成的两个分⽀的熵最⼤的特征和阈值。

按照该标准分⽀得到两
个新节点,⽤同样的⽅法进⾏分⽀,直到所有⼈被分⼊性别唯⼀的叶⼦节点,或达到预设的终
⽌条件,若最终叶⼦节点中性别不唯⼀,则以多数⼈的性别作为该叶⼦节点的性别。

回归树总体流程也是类似,不过在每个节点(不⼀定是叶⼦节点)都会得到预测值,以年龄为例,
该预测值等于属于这个节点的所有⼈年龄的平均值。

分⽀时穷举每个特征的每个阈值,找最好
的分割点,但衡量的标准变成了最⼩化均⽅误差,即(每个⼈的年龄-预测年龄)^2 的总和 /
N,或者说是每个⼈的预测误差平⽅和除以 N。

这很好理解,被预测出粗的⼈数越多,错的越
离谱,均⽅误差越⼤,通过最⼩化均⽅误差找最靠谱的分⽀依据。

分⽀直到每个叶⼦节点上的
⼈的年龄都唯⼀(这太难了),或者达到预设的终⽌条件(如叶⼦个数上限),若最终叶⼦节点上⼈
的年龄不唯⼀,则以该节点上所有⼈的平均年龄作为该叶⼦节点的预测年龄。

⼆.随机森林
先补充组合分类器的概念,将多个分类器的结果进⾏多票表决或取平均值,以此作为最终的结
果。

1.构建组合分类器的好处:
(1)提升模型精度:整合各个模型的分类结果,得到更合理的决策边界,减少整体错误呢,实现
更好的分类效果:
(2)处理过⼤或过⼩的数据集:数据集较⼤时,可将数据集划分成多个⼦集,对⼦集构建分类
器;当数据集较⼩时,通过⾃助采样(bootstrap)从原始数据集采样产⽣多组不同的数据集,构建
分类器。

(3)若决策边界过于复杂,则线性模型不能很好地描述真实情况。

因此,现对于特定区域的数据集,训练多个线性分类器,再将他们集成。

(4)⽐较适合处理多源异构数据(存储⽅式不同(关系型、⾮关系型),类别不同(时序型、离散型、连续型、⽹络结构数据))
随机森林是⼀个多决策树的组合分类器,随机主要体现在两个⽅⾯:数据选取的随机性和特征选取的随机性。

(1)数据的随机选取
第⼀,从原始数据集中采取有放回的抽样(bootstrap),构造⼦数据集,⼦数据集扥数量和原始数据集的数量⼀样。

不同的⼦数据集的元素可以重复,同⼀个⼦数据集中的元素也可以重复。

第⼆,利⽤⼦数据集构建⼦决策树,将这个数据放到每个⼦决策树中,每个⼦决策树输出⼀个结果。

最后,如果有了新的数据需啊哟通过随机森林得到分类结果,就可以通过⼦决策树的判断结果来投票,得到随机森林的输出结果。

如下图,假设随机森林中有3棵⼦决策树,2棵⼦树的分类结果是A类,1棵⼦树的分类结果是B类,那么随机森林的分类结果就是A类。

(2)待选特征的随机选取
类似于数据集的随机选取,随即森林中的⼦树的每⼀个分裂过程并未⽤到所有的待选特征,⽽是从所有的待选特征中随机选取⼀定的特征,之后再在随机选取的特征中选择最优的特征。

这样能使随机森林中的决策树能不同,提升系统的多样性,从⽽提升分类性能。

组合树⽰例图
三、GBDT和XGBoost
1.在讲GBDT和XGBoost之前先补充Bagging和Boosting的知识。

Bagging是并⾏的学习算法,思想很简单,即每⼀次从原始数据中根据均匀概率分布有放回的抽取和原始数据集⼀样⼤⼩的数据集合。

样本点可以出现重复,然后对每⼀次产⽣的数据集构造⼀个分类器,再对分类器进⾏组合。

Boosting的每⼀次抽样的样本分布是不⼀样的,每⼀次迭代,都是根据上⼀次迭代的结果,增加被错误分类的样本的权重。

使模型在之后的迭代中更加注重难以分类的样本。

这是⼀个不断学习的过程,也是⼀个不断提升的过程,这就是Boosting思想的本质所在。

迭代之后,将每次迭代的基分类器进⾏集成,那么如何进⾏样本权重的调整和分类器的集成是我们需要考虑的关键问题。

Boosting算法结构图
以著名的Adaboost算法举例:
有⼀个数据集,样本⼤⼩为N,每⼀个样本对应⼀个原始标签起初,我们初始化样本的权重为
1/N
计算的是当前数据下,模型的分类误差率,模型的系数值是基于分类误差率的
根据模型的分类结果,更新原始数据中数据的分布,增加被错分的数据被抽中的概率,以便下⼀次迭代的时候能被模型重新训练
最终的分类器是各个基分类器的组合
2.GBDT
GBDT是以决策树(CART)为基学习器的GB算法,是迭代树⽽不是分类树,Boost是'提升'的意思,⼀般Boosting算法都是⼀个迭代的过程,每⼀次新的训练都是为了改进上⼀次的结果。

有了前⾯Adaboost的铺垫,⼤家应该能很容易理解⼤体思想。

GBDT的核⼼是:每⼀棵树学习的是之前所有树结论和的残差。

这个残差就是⼀个加预测值后能得真实值的累加量。

⽐如A的真实年龄是18岁,但第⼀棵树的预测年龄是12岁,差了6岁,即残差为6岁。

那么在第⼆棵树⾥我们把A的年龄设为6岁去学习,如果第⼆棵树真的能把A分到6岁的叶⼦节点,那累加两棵树的结论就是A的真实年龄;如果第⼆棵树的结论是5岁,则A仍然存在1岁的残差,第三棵树⾥A的年龄就变成1岁,继续学习。

3.XGBoost
XGBoostt相⽐于GBDT来说,更加有效应⽤了数值优化,最重要是对损失函数(预测值和真实值的误差)变得更复杂。

⽬标函数依然是所有树的预测值相加等于预测值。

损失函数如下,引⼊了⼀阶导数,⼆阶导数:
好的模型需要具备两个基本要素:⼀是要有好的精度(即好的拟合程度),⼆是模型要尽可能的简单(复杂的模型容易出现过拟合,并且更加不稳定)因此,我们构建的⽬标函数右边第⼀项是模型的误差项,第⼆项是正则化项(也就是模型复杂度的惩罚项)
常⽤的误差项有平⽅误差和逻辑斯蒂误差,常见的惩罚项有l1,l2正则,l1正则是将模型各个元素进⾏求和,l2正则是对元素求平⽅。

每⼀次迭代,都在现有树的基础上,增加⼀棵树去拟合前⾯树的预测结果与真实值之间的残差⽬标函数如上图,最后⼀⾏画圈部分实际上就是预测值和真实值之间的残差
先对训练误差进⾏展开:
xgboost则对代价函数进⾏了⼆阶泰勒展开,同时⽤到了残差平⽅和的⼀阶和⼆阶导数
再研究⽬标函数中的正则项:
树的复杂度可以⽤树的分⽀数⽬来衡量,树的分⽀我们可以⽤叶⼦结点的数量来表⽰
那么树的复杂度式⼦:右边第⼀项是叶⼦结点的数量T,第⼆项是树的叶⼦结点权重w的l2正则化,正则化是为了防⽌叶⼦结点过多
此时,每⼀次迭代,相当于在原有模型中增加⼀棵树,⽬标函数中,我们⽤wq(x)表⽰⼀棵树,包括了树的结构以及叶⼦结点的权重,w表⽰权重(反映预测的概率),q表⽰样本所在的索引号(反映树的结构)
将最终得到的⽬标函数对参数w求导,带回⽬标函数,可知⽬标函数值由红⾊⽅框部分决定:因此,xgboost的迭代是以下图中gain式⼦定义的指标选择最优分割点的:
那么如何得到优秀的组合树呢?
⼀种办法是贪⼼算法,遍历⼀个节点内的所有特征,按照公式计算出按照每⼀个特征分割的信息增益,找到信息增益最⼤的点进⾏树的分割。

增加的新叶⼦惩罚项对应了树的剪枝,当gain ⼩于某个阈值的时候,我们可以剪掉这个分割。

但是这种办法不适⽤于数据量⼤的时候,因此,我们需要运⽤近似算法。

另⼀种⽅法:XGBoost在寻找splitpoint的时候,不会枚举所有的特征值,⽽会对特征值进⾏聚合统计,按照特征值的密度分布,构造直⽅图计算特征值分布的⾯积,然后划分分布形成若⼲个bucket(桶),每个bucket的⾯积相同,将bucket边界上的特征值作为split
point的候选,遍历所有的候选分裂点来找到最佳分裂点。

上图近似算法公式的解释:将特征k的特征值进⾏排序,计算特征值分布,rk(z)表⽰的是对于特征k⽽⾔,其特征值⼩于z的权重之和占总权重的⽐例,代表了这些特征值的重要程度,我们按照这个⽐例计算公式,将特征值分成若⼲个bucket,每个bucket的⽐例相同,选取这⼏类特征值的边界作为划分候选点,构成候选集;选择候选集的条件是要使得相邻的两个候选分裂节点差值⼩于某个阈值
综合以上所述,我们可以得到xgboost相⽐于GBDT的创新之处:
传统GBDT以CART作为基分类器,xgboost还⽀持线性分类器,这个时候xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。

传统GBDT在优化时只⽤到⼀阶导数信息,xgboost则对代价函数进⾏了⼆阶泰勒展开,同时⽤到了⼀阶和⼆阶导数。

顺便提⼀下,xgboost⼯具⽀持⾃定义代价函数,只要函数可⼀阶和⼆阶求导。

xgboost在代价函数⾥加⼊了正则项,⽤于控制模型的复杂度。

正则项⾥包含了树的叶⼦节点个数、每个叶⼦节点上输出的score的L2模的平⽅和。

从Bias-variance tradeoff⾓度来讲,正则项降低了模型的variance,使学习出来的模型更加简单,防⽌过拟合,这也是xgboost优于传统GBDT的⼀个特性。

Shrinkage(缩减),相当于学习速率(xgboost中的eta)。

每次迭代,增加新的模型,在前⾯成上⼀个⼩于1的系数,降低优化的速度,每次⾛⼀⼩步逐步逼近最优模型⽐每次⾛⼀⼤步逼近更加容易避免过拟合现象;
列抽样(column subsampling)。

xgboost借鉴了随机森林的做法,⽀持列抽样(即每次的输⼊特征不是全部特征),不仅能降低过拟合,还能减少计算,这也是xgboost异于传统gbdt的⼀个特性。

忽略缺失值:在寻找splitpoint的时候,不会对该特征为missing的样本进⾏遍历统计,只对该列特征值为non-missing的样本上对应的特征值进⾏遍历,通过这个⼯程技巧来减少了为稀疏离散特征寻找splitpoint的时间开销
指定缺失值的分隔⽅向:可以为缺失值或者指定的值指定分⽀的默认⽅向,为了保证完备性,会分别处理将missing该特征值的样本分配到左叶⼦结点和右叶⼦结点的两种情形,分到那个⼦节点带来的增益⼤,默认的⽅向就是哪个⼦节点,这能⼤⼤提升算法的效率。

并⾏化处理:在训练之前,预先对每个特征内部进⾏了排序找出候选切割点,然后保存为block 结构,后⾯的迭代中重复地使⽤这个结构,⼤⼤减⼩计算量。

在进⾏节点的分裂时,需要计算每个特征的增益,最终选增益最⼤的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进⾏,即在不同的特征属性上采⽤多线程并⾏⽅式寻找最佳分割点。

相关文档
最新文档