机器学习之ID3、C4.5、CART、RF、boosting、Adaboost、GBDT、xgboost模型

决策树

决策树是一个有监督的分类模型,其本质是选择一个能带来最大信息增益的特征值进行树的分割,直到到达结束条件或者叶子结点纯度到达一定阈值。
按照分割指标和分割方法,决策树的经典模型可以分为ID3、C4.5以及CART

ID3:以信息增益为准则来选择最优划分属性

信息增益的计算要基于信息熵(度量样本集合纯度的指标)
在这里插入图片描述
信息熵越小,数据集X的纯度越大
因此,假设于数据集D上建立决策树,数据有K个类别:
在这里插入图片描述
公式(1)中:
在这里插入图片描述
表示第k类样本的数据占数据集D样本总数的比例
公式(2)表示的是以特征A作为分割的属性,得到的信息熵:

Di表示的是以属性A为划分,分成n个分支,第i个分支的节点集合

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

公式(3)为分割后与分割前的信息熵的差值,也就是信息增益,越大越好

但是这种分割算法存在一定的缺陷:

假设每个记录有一个属性“ID”,若按照ID来进行分割的话,由于ID是唯一的,因此在这一个属性上,能够取得的特征值等于样本的数目,也就是说ID的特征值很多。那么无论以哪个ID为划分,叶子结点的值只会有一个,纯度很大,得到的信息增益会很大,但这样划分出来的决策树是没意义的。由此可见,ID3决策树偏向于取值较多的属性进行分割,存在一定的偏好。为减小这一影响,有学者提出C4.5的分类算法。

C4.5:基于信息增益率准则选择最优分割属性的算法

信息增益比率通过引入一个被称作分裂信息(Split information)的项来惩罚取值较多的属性。
在这里插入图片描述
上式,分子计算与ID3一样,分母是由属性A的特征值个数决定的,个数越多,IV值越大,信息增益率越小,这样就可以避免模型偏好特征值多的属性,但是聪明的人一看就会发现,如果简单的按照这个规则来分割,模型又会偏向特征数少的特征。因此C4.5决策树先从候选划分属性中找出信息增益高于平均水平的属性,在从中选择增益率最高的。

对于连续值属性来说,可取值数目不再有限,因此可以采用离散化技术(如二分法)进行处理。将属性值从小到大排序,然后选择中间值作为分割点,数值比它小的点被划分到左子树,数值不小于它的点被分到又子树,计算分割的信息增益率,选择信息增益率最大的属性值进行分割。

CART:以基尼系数为准则选择最优划分属性,可以应用于分类和回归

CART是一棵二叉树,采用二元切分法,每次把数据切成两份,分别进入左子树、右子树。而且每个非叶子节点都有两个孩子,所以CART的叶子节点比非叶子多1。相比ID3和C4.5,CART应用要多一些,既可以用于分类也可以用于回归。CART分类时,使用基尼指数(Gini)来选择最好的数据分割的特征,gini描述的是纯度,与信息熵的含义相似。CART中每一次迭代都会降低GINI系数。
在这里插入图片描述
Gini(D)反映了数据集D的纯度,值越小,纯度越高。我们在候选集合中选择使得划分后基尼指数最小的属性作为最优化分属性。
CART

分类树和回归树

提到决策树算法,很多想到的就是上面提到的ID3、C4.5、CART分类决策树。其实决策树分为分类树和回归树,前者用于分类,如晴天/阴天/雨天、用户性别、邮件是否是垃圾邮件,后者用于预测实数值,如明天的温度、用户的年龄等。

作为对比,先说分类树,我们知道ID3、C4.5分类树在每次分枝时,是穷举每一个特征属性的每一个阈值,找到使得按照feature<=阈值,和feature>阈值分成的两个分枝的熵最大的feature和阈值。按照该标准分枝得到两个新节点,用同样方法继续分枝直到所有人都被分入性别唯一的叶子节点,或达到预设的终止条件,若最终叶子节点中的性别不唯一,则以多数人的性别作为该叶子节点的性别。

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

随机森林

组合分类器的概念,将多个分类器的结果进行多票表决或者是取平均值,以此作为最终的结果。
构建组合分类器的好处:

  1. 提升模型精度:整合各个模型的分类结果,得到更合理的决策边界,减少整体错误,实现更好的分类效果;
  2. 处理过大或过小的数据集:数据集较大时,可以将数据集划分成多个子集,对子集构建分类器;数据集较小时,可通过多种抽样方式(bootstrap)从原始数据集抽样产生多组不同的数据集,构建分类器。
  3. 若决策边界过于复杂,则线性模型不能很好地描述真实情况。因此先对于特定区域的数据集,训练多个线性分类器,再将它们集成。
  4. 比较适合处理多源异构数据(存储方式不同(关系型、非关系型),类别不同(时序型、离散型、连续型、网络结构数据))

随机森林是一个典型的多个决策树的组合分类器。主要包括两个方面:数据的随机性选取,以及待选特征的随机选取。

  1. 数据的随机选取
    第一,从原始的数据集中采取有放回的抽样(bootstrap),构造子数据集,子数据集的数据量是和原始数据集相同的。不同子数据集的元素可以重复,同一个子数据集中的元素也可以重复。
    第二,利用子数据集来构建子决策树,将这个数据放到每个子决策树中,每个子决策树输出一个结果。最后,如果有了新的数据需要通过随机森林得到分类结果,就可以通过对子决策树的判断结果的投票,得到随机森林的输出结果了。如下图,假设随机森林中有3棵子决策树,2棵子树的分类结果是A类,1棵子树的分类结果是B类,那么随机森林的分类结果就是A类。
    在这里插入图片描述
  2. 待选特征的随机选取
    与数据集的随机选取类似,随机森林中的子树的每一个分裂过程并未用到所有的待选特征,而是从所有的待选特征中随机选取一定的特征,之后再在随机选取的特征中选取最优的特征。这样能够使得随机森林中的决策树都能够彼此不同,提升系统的多样性,从而提升分类性能。
    在这里插入图片描述

GBDT和xgboost

bagging和boosting

Bagging的思想比较简单,即每一次从原始数据中根据均匀概率分布有放回的抽取和原始数据大小相同的样本集合,样本点可能出现重复,然后对每一次产生的训练集构造一个分类器,再对分类器进行组合。

boosting的每一次抽样的样本分布都是不一样的。每一次迭代,都根据上一次迭代的结果,增加被错误分类的样本的权重,使得模型能在之后的迭代中更加注意到难以分类的样本,这是一个不断学习的过程,也是一个不断提升的过程,这也就是boosting思想的本质所在。迭代之后,将每次迭代的基分类器进行集成。那么如何进行样本权重的调整和分类器的集成是我们需要考虑的关键问题。
在这里插入图片描述

Adaboost算法

在这里插入图片描述
我们有一个数据集,样本大小为N,每一个样本对应一个原始标签起初,我们初始化样本的权重为1/N
在这里插入图片描述
Gm计算的是当前数据下,模型的分类误差率,模型的系数值是基于分类误差率的
在这里插入图片描述
根据模型的分类结果,更新原始数据中数据的分布,增加被错分的数据被抽中的概率,以便下一次迭代的时候能被模型重新训练
在这里插入图片描述

GBDT

GBDT(Gradient boosting Decision Tree)是以决策树(CART)为基学习器的GB(Gradient boosting)算法,是迭代树,而不是分类树。Boost是"提升"的意思,一般Boosting算法都是一个迭代的过程,每一次新的训练都是为了改进上一次的结果。有了前面Adaboost的铺垫,大家应该能很容易理解大体思想。
在这里插入图片描述
GBDT的核心就在于:每一棵树学的是之前所有树结论和的残差这个残差就是一个加预测值后能得真实值的累加量。比如A的真实年龄是18岁,但第一棵树的预测年龄是12岁,差了6岁,即残差为6岁。那么在第二棵树里我们把A的年龄设为6岁去学习,如果第二棵树真的能把A分到6岁的叶子节点,那累加两棵树的结论就是A的真实年龄;如果第二棵树的结论是5岁,则A仍然存在1岁的残差,第三棵树里A的年龄就变成1岁,继续学习。
在这里插入图片描述

GBDT的“梯度提升”怎么理解?

我们可以把 gbdt 的求解过程想象成线性模型优化的过程。
在线性模型优化的过程中。利用梯度下降(公式如下减去梯度) ,我们总是让参数向负梯度的方向移动(理解为加上负梯度,gbdt是加法模型),使损失函数最小。
w r + 1 = w T − α ∇ E ( w T ) = w T + ( − α ∇ E ( w T ) ) w^{r+1}=w^T-\alpha\nabla E(w^T)=w^T + (-\alpha\nabla E(w^T)) wr+1=wTαE(wT)=wT+(αE(wT))
现在来看 gbdt,假入我们现在有 t 课树,我们需要去学习是第 t+1 颗树,那么如何学习第 t+1 颗树才是最优的树呢? 这个时候我们参考梯度优化的思想。现在的 t 课树就是我们现在的状态使用这个状态我们可以计算出现在的损失。如何让损失更小呢?我们只需要让 t+1 颗树去拟合损失的负梯度。正是借用了梯度优化的思想。

区别是梯度下降思想从参数空间到函数空间

xgboost

Xgboost相比于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如何优化、如何计算,但树到底长啥样,我们却一直没看到。很显然,一棵树的生成是由一个节点一分为二,然后不断分裂最终形成为整棵树。那么树怎么分裂的就成为了接下来我们要探讨的关键。对于一个叶子节点如何进行分裂,XGBoost作者在其原始论文中给出了一种分裂节点的方法:枚举所有不同树结构的贪心法

不断地枚举不同树的结构,然后利用打分函数来寻找出一个最优结构的树,接着加入到模型中,不断重复这样的操作。这个寻找的过程使用的就是贪心算法。选择一个feature分裂,计算loss function最小值,然后再选一个feature分裂,又得到一个loss function最小值,你枚举完,找一个效果最好的,把树给分裂,就得到了小树苗。

总而言之,XGBoost使用了和CART回归树一样的想法,利用贪婪算法,遍历所有特征的所有特征划分点,不同的是使用的目标函数不一样。具体做法就是分裂后的目标函数值比单子叶子节点的目标函数的增益,同时为了限制树生长过深,还加了个阈值,只有当增益大于该阈值才进行分裂。从而继续分裂,形成一棵树,再形成一棵树,每次在上一次的预测基础上取最优进一步分裂/建树。

如何停止树的循环生成

凡是这种循环迭代的方式必定有停止条件,什么时候停止呢?简言之,设置树的最大深度、当样本权重和小于设定阈值时停止生长以防止过拟合。具体而言,则

引入的分裂带来的增益小于设定阀值的时候,我们可以忽略掉这个分裂,所以并不是每一次分裂loss function整体都会增加的,有点预剪枝的意思,阈值参数为(即正则项里叶子节点数T的系数);
树达到最大深度时则停止建立决策树,设置一个超参数max_depth,避免树太深导致学习局部样本,从而过拟合;
样本权重和小于设定阈值时则停止建树。什么意思呢,即涉及到一个超参数-最小的样本权重和min_child_weight,和GBM的 min_child_leaf 参数类似,但不完全一样。大意就是一个叶子节点样本太少了,也终止同样是防止过拟合;

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结构,后面的迭代中重复地使用这个结构,大大减小计算量。在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行,即在不同的特征属性上采用多线程并行方式寻找最佳分割点。

参考boost系列
优缺点

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: AdaboostGBDTXGBoost和LightGBM都是机器学习中常用的集成学习算法。 Adaboost是一种迭代算法,通过不断调整样本权重和分类器权重,逐步提高分类器的准确率。 GBDT(Gradient Boosting Decision Tree)是一种基于决策树的集成学习算法,通过不断迭代,每次训练一个新的决策树来纠正前面树的错误,最终得到一个强分类器。 XGBoost是一种基于GBDT的算法,它在GBDT的基础上引入了正则化和并行化等技术,使得模型更加准确和高效。 LightGBM是一种基于GBDT的算法,它采用了基于直方图的决策树算法和互斥特征捆绑技术,使得模型训练速度更快,占用内存更少,同时也具有较高的准确率。 ### 回答2: adaboost(Adaptive Boosting) 是一种基于不同权重的弱分类器的算法,它通过迭代的方式来逐步提高分类器的准确性。在每轮迭代中,它会调整训练样本的权重,使得前一轮分类错误的样本在当前轮得到更多的关注。最终,通过组合这些弱分类器来构建一个强分类器。其优点在于不易过拟合,但需要耗费大量的时间来训练和预测。 gbdt(Gradient Boosting Decision Tree) 是一种基于决策树的集成学习算法,它通过迭代的方式来提升分类器的准确性。基于训练样本和实际输出的误差进行梯度下降,将它们作为下一个分类器的训练数据。每个分类器都在之前所有分类器得到的残差的基础上进行训练,并且将它们组合成一个最终的分类器。在训练过程中,为了避免过拟合,可以限制决策树的深度等参数,并采用交叉验证等技术。gbdt可以处理缺失数据、不平衡分类和高维度数据等问题,但需要注意过拟合的问题。 xgboost(Extreme Gradient Boosting) 是一种基于决策树的集成学习算法,它在gbdt的基础上引入了正则化项和精细的特征选择,进一步提高了分类器的准确性和效率。通过Hessian矩阵对损失函数进行二阶泰勒展开,引入正则化约束,可以优化损失函数,并通过交叉验证等技术选择最优的超参数。xgboost还支持GPU加速,提高模型训练的速度和效率,但需要更多的计算资源。xgboost在分类、回归和排名任务中表现优异,但需要注意过拟合和计算量的问题。 lightgbm是微软旗下一款高效、快速、分布式的梯度提升框架,也是一种基于决策树的集成学习算法,定位在处理高维度数据和大规模数据集上。lightgbm采用了GOSS(Gradient-based One-Side Sampling)技术和EFB(Exclusive Feature Bundling)技术对数据进行处理,大大减少数据的内存占用和训练时间。同时,还支持并行计算和GPU加速,提高了模型的速度和效率。lightgbm在排序、分类、回归等任务中表现出色,只是对离群值敏感,需要对数据进行预处理。 ### 回答3: Adaboost,Gradient Boosting Decision Tree (GBDT),XGBoost和LightGBM都是常见的集成学习算法,它们用于提高模型在复杂数据集上的准确度,并处理复杂数据集上遇到的问题。 Adaboost是一种迭代算法,每次迭代它使用提高错误分类样本的加权值,并降低正确分类样本的加权值,以便让前一个弱分类器无法捕捉并由后续分类器学习。Adaboost弱分类器快速训练和预测,且不需要太多超参数调整,但是它倾向于过度拟合数据,并且实力可能不足以解决大型数据集的问题。 GBDT使用决策树作为弱分类器,将每一棵树的预测结果作为下一棵树的预测输入,最后对所有树的预测结果进行加权求和。GBDT可以很好地处理线性和非线性问题,但是它倾向于过度拟合数据,需要进行精细调整参数,并且需要较长时间的训练时间。 XGBoost结合了GBDT的优势和树的强大性质。它采用了一些优秀的技术,如Boosting树算法,Shrinkage,Column Sampling和Pruning Nodes,以提高模型的性能和降低过拟合风险。XGBoost可以处理大规模数据集和高维数据集,并且速度较快,但需要的资源较多,如内存、计算能力和高质量的数据集。 LightGBM是XGBoost的新一代版本,采用了GOI(Gradient-based One-side Sampling)算法和Histogram-based Gradient Boosting方法来加快训练速度和降低内存占用。GOI算法通过对数据进行一侧采样来提高训练速度,而直方图梯度提升方法将节点分裂建模为一个直方图分桶过程,以减少节点分裂的计算成本。LightGBM对大数据集的处理能力很强,速度相对较快,但对于处理小数据集的效果可能不明显。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值