概述
Xgboost属于集成算法。
复习一下:
0、XGB vs GBDT
- 正则项:在使用CART作为基分类器时,XGBoost显式地加入了正则项来控制模型的复杂度,有利于防止过拟合,从而提高模型的泛化能力。
- 二阶导数:GBDT在模型训练时只使用了代价函数的一阶导数信息,XGBoost对代价函数进行二阶泰勒展开,可以同时使用一阶和二阶导数。
- 基分类器:传统的GBDT采用CART作为基分类器,XGBoost支持多种类型的基分类器,比如线性分类器。
- 列采样:传统的GBDT在每轮迭代时使用全部的数据,XGBoost则采用了与随机森林相似的策略,支持对数据进行采样,支持列抽样,不仅能降低过拟合,还能减少计算,这也是xgboost异于传统gbdt的一个特性。
- 缺失值处理:传统的GBDT没有设计对缺失值进行处理,XGBoost可以自动学习出它的分裂方向。XGBoost对于确实值能预先学习一个默认的分裂方向。
- Shrinkage(缩减),相当于学习速率(xgboost中的eta)。xgboost在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。实际应用中,一般把eta设置得小一点,然后迭代次数设置得大一点。(补充:传统GBDT的实现也有学习速率)
1、XGBoost树的定义
举个例子,我们要预测一家人对电子游戏的喜好程度,考虑到年轻和年老相比,年轻更可能喜欢电子游戏,以及男性和女性相比,男性更喜欢电子游戏,故先根据年龄大小区分小孩和大人,然后再通过性别区分开是男是女,逐一给各人在电子游戏喜好程度上打分,如下图所示。
就这样,训练出了2棵树tree1和tree2,类似之前gbdt的原理,两棵树的结论累加起来便是最终的结论,所以小孩的预测分数就是两棵树中小孩所落到的结点的分数相加:2 + 0.9 = 2.9。爷爷的预测分数同理:-1 + (-0.9)= -1.9。具体如下图所示
恩,你可能要拍案而起了,惊呼,这不是跟gbdt乃异曲同工么?
事实上,如果不考虑工程实现、解决问题上的一些差异,xgboost与gbdt比较大的不同就是目标函数的定义。xgboost的目标函数如下图所示:
其中
- 红色箭头所指向的L即为损失函数如:
- 平方损失函数:
- logistic损失函数:
- 红色方框所框起来的是正则项(包括L1正则、L2正则)
- 红色圆圈所圈起来的为常数项
- 对于f(x),xgboost利用泰勒展开三项,做一个近似
2、XGBoost的核心算法思想不难,基本就是:
不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数f(x),去拟合上次预测的残差。
当我们训练完成得到k棵树,我们要预测一个样本的分数,其实就是根据这个样本的特征,在每棵树中会落到对应的一个叶子节点,每个叶子节点就对应一个分数
最后只需要将每棵树对应的分数加起来就是该样本的预测值。
显然,我们的目标是要使得树群的预测值y′i尽量接近真实值yi,而且有尽量大的泛化能力。类似之前GBDT的套路,XGBoost也是需要将多棵树的得分累加得到最终的预测得分 (每一次迭代,都在现有树的基础上,增加一棵树去拟合前面树的预测结果与真实值之间的残差)。
我们再来看一下XGBoost的目标函数(损失函数揭示训练误差 + 正则化定义复杂度):
正则化公式也就是目标函数的后半部分,对于上式而言,y′i是整个累加模型的输出,正则化项∑kΩ(ft)是则表示树的复杂度的函数,值越小复杂度越低,泛化能力越强。
3、Xgboost目标函数
看下整体推导流程图:
3.1 推导:
核心:怎么切分树,得到什么样的评估标准,用这个评估标准去评估。
每一个样本都会落在叶子节点上。
所以: 把在样本上遍历转换成在叶子节点上进行遍历。
建立模型是为了要模型的结果,模型的效果,也就是一些值。
3.2 理解目标函数
它表示了这棵树的结构有多好,值越小,代表这样结构越好!也就是说,它是衡量第t棵CART树的结构好坏的标准。注意注意注意~,**这个值仅仅是用来衡量结构的好坏的,与叶子节点的值可是无关的。**为什么?请再仔细看一下obj的推导过程。obj只和Gj和Hj和T有关,而它们又只和树的结构(q(x))有关,与叶子节点的值可是半毛关系没有。如下图所示:
4、Xgboost优点:
1、w是最优化求出来的,不是啥平均值或者规则指定的,算是思路上的新颖。
2、正则化防止过拟合的技术,loss function里面就有。
3、支持自定义loss function,只要能泰勒展开(能求一阶导和二阶导)就行
4、属于boosting,本身是串行的(树与树之间是串行的)。但是xgboost支持并行化(在选择最佳分裂点,进行枚举的时候并行),直接的效果就是训练快。
4.1 Xgboost与深度学习的关系:
- Xgboost第一感觉是防止过拟合+各种支持分布式/并行,所以一般传言这种必杀器效果好(集成学习的高配)+训练效率高(分布式),与深度学习相比,对样本量和特征数据类型要求没有那么严格,适用范围广。
- 不同的机器学习模型适用于不同类型的任务。深度神经网络通过对时空位置建模,能够很好的捕获图像,语音,文本等高维数据。而基于树模型的XGboost则能够很好的处理表格数据,同时还拥有一些深度神经网络所没有的特性(如模型的可解释性,输入数据的不变形,更易于调参等。)
- 这两类模型都很重要,并广泛适用于竞赛和工业界。举例来说,几乎所有采用机器学习技术的公司都在用tree boosting,XGboost已经给工业界带来了很大的影响。
5、其他细节
5.1 缺失值处理
- 在训练阶段寻找分裂点的时候,计算的分裂增益不包含缺失值样本。在逻辑实现上,为了保证完备性,会分别将缺失该特征值的样本分配到左叶子结点和右叶子结点的两种情形,计算增益后选择增益大的方向归类含缺失值样本。
- 在预测阶段,如果训练集没有缺失值而测试集出现缺失值,则要为缺失值(或者指定的值未出现的值)指定分支的默认方向,预测时自动将缺失值的划分到这一分支。
5.2 剪枝策略
- 预剪枝
- 当最优分裂点对应的增益值为负时停止分裂
- 但是这也会存在问题,即将来的某个时刻能够获取更高的增益
- 后剪枝
- 将决策树增长到它的最大深度,递归的进行剪枝,剪去那些使得增益值为负值的叶子节点
5.3 Shrinkage和列子抽样(column subsampling)
除了正则化目标函数外,还会使用两种额外的技术来进一步阻止overfitting。
- 第一种技术是Friedman介绍的Shrinkage。Shrinkage会在每一步tree boosting时,会将新加入的weights通过一个因子η进行缩放。与随机优化中的learning rate相类似,对于用于提升模型的新增树(future trees),shrinkage可以减少每棵单独的树、以及叶子空间(leaves space)的影响。
- 第二个技术是列特征子抽样(column feature subsampling)。该技术也会在RandomForest中使用,根据用户的反馈,比起传统的行子抽样(row sub-sampling:同样也支持),使用列子抽样可以阻止overfitting。列子抽样的使用可以加速并行算法的计算。
5.3 特征选择
xgboost get_fscore 判断特征重要程度的三种指标
- ‘weight’ - the number of times a feature is used to split the data across all trees.
- ‘gain’ - the average gain of the feature when it is used in trees.
- ‘cover’ - the average coverage of the feature when it is used in trees.
6、常见的问题:
6.1 树该怎么长
很有意思的一个事是,我们从头到尾了解了xgboost如何优化、如何计算,但树到底长啥样,我们却一直没看到。很显然,一棵树的生成是由一个节点一分为二,然后不断分裂最终形成为整棵树。那么树怎么分裂的就成为了接下来我们要探讨的关键。对于一个叶子节点如何进行分裂,XGBoost作者在其原始论文中给出了一种分裂节点的方法:枚举所有不同树结构的贪心法
不断地枚举不同树的结构,然后利用打分函数来寻找出一个最优结构的树,接着加入到模型中,不断重复这样的操作。这个寻找的过程使用的就是贪心算法。选择一个feature分裂,计算loss function最小值,然后再选一个feature分裂,又得到一个loss function最小值,你枚举完,找一个效果最好的,把树给分裂,就得到了小树苗。
总而言之,XGBoost使用了和CART回归树一样的想法,利用贪婪算法,遍历所有特征的所有特征划分点,不同的是使用的目标函数不一样。具体做法就是分裂后的目标函数值比单子叶子节点的目标函数的增益,同时为了限制树生长过深,还加了个阈值,只有当增益大于该阈值才进行分裂。从而继续分裂,形成一棵树,再形成一棵树,每次在上一次的预测基础上取最优进一步分裂/建树。
6.2 如何停止树的循环生成
凡是这种循环迭代的方式必定有停止条件,什么时候停止呢?简言之,设置树的最大深度、当样本权重和小于设定阈值时停止生长以防止过拟合。具体而言,则
当引入的分裂带来的增益小于设定阀值的时候,我们可以忽略掉这个分裂,所以并不是每一次分裂loss function整体都会增加的,有点预剪枝的意思,阈值参数为(即正则项里叶子节点数T的系数);
当树达到最大深度时则停止建立决策树,设置一个超参数max_depth,避免树太深导致学习局部样本,从而过拟合;
样本权重和小于设定阈值时则停止建树。什么意思呢,即涉及到一个超参数-最小的样本权重和min_child_weight,和GBM的 min_child_leaf 参数类似,但不完全一样。大意就是一个叶子节点样本太少了,也终止同样是防止过拟合;
6.3 XGBoost与GBDT有什么不同
除了算法上与传统的GBDT有一些不同外,XGBoost还在工程实现上做了大量的优化。总的来说,两者之间的区别和联系可以总结成以下几个方面。
GBDT是机器学习算法,XGBoost是该算法的工程实现。
在使用CART作为基分类器时,XGBoost显式地加入了正则项来控制模 型的复杂度,有利于防止过拟合,从而提高模型的泛化能力。
GBDT在模型训练时只使用了代价函数的一阶导数信息,XGBoost对代 价函数进行二阶泰勒展开,可以同时使用一阶和二阶导数。
传统的GBDT采用CART作为基分类器,XGBoost支持多种类型的基分类 器,比如线性分类器。
传统的GBDT在每轮迭代时使用全部的数据,XGBoost则采用了与随机 森林相似的策略,支持对数据进行采样。
传统的GBDT没有设计对缺失值进行处理,XGBoost能够自动学习出缺 失值的处理策略。
6.4 为什么XGBoost要用泰勒展开,优势在哪里?
XGBoost使用了一阶和二阶偏导, 二阶导数有利于梯度下降的更快更准. 使用泰勒展开取得函数做自变量的二阶导数形式, 可以在不选定损失函数具体形式的情况下, 仅仅依靠输入数据的值就可以进行叶子分裂优化计算, 本质上也就把损失函数的选取和模型算法优化/参数选择分开了. 这种去耦合增加了XGBoost的适用性, 使得它按需选取损失函数, 可以用于分类, 也可以用于回归。
6.5 为什么要用二阶导?
首先我们需要明确一个概念, 我们的boosting每一轮迭代是在优化什么呢? 换句话说我们在用损失函数l ll在干什么呢? 其实我们看Boosting的框架, 无论是GBDT还是Adaboost, 其在每一轮迭代中, 根本没有理会损失函数具体是什么, 仅仅用到了损失函数的一阶导数。仅仅用一阶导数的问题就是, 我们根本无法保证我们找到的是全局最优。除非问题f(x)本身是强凸的而且最好是smooth的。每次迭代相当于就是最优化负梯度。即下式中的▽f(xi)因为是负梯度所以前面要加负号, c代表学习率。
有没有感觉这个公式形式很熟悉, 是不是就是一般常见的linear regression 的 stochastic 梯度更新公式。既然GBDT用的是Stochastic Gradient Descent, 我们回想一下, 是不是还有别的梯度更新的方式, 这时, 牛顿法 Newton’s method就出现了。可以说, XGBoost是用了牛顿法进行的梯度更新。仅仅用一阶导数的问题就是, 我们根本无法保证我们找到的是全局最优。
更多的计算过程可参考:https://blog.csdn.net/v_JULY_v/article/details/81410574
小结:
最后
以上就是成就月光为你收集整理的XGBOOST理论理解③0、XGB vs GBDT1、XGBoost树的定义2、XGBoost的核心算法思想不难,基本就是:3、Xgboost目标函数4、Xgboost优点:5、其他细节6、常见的问题:小结:的全部内容,希望文章能够帮你解决XGBOOST理论理解③0、XGB vs GBDT1、XGBoost树的定义2、XGBoost的核心算法思想不难,基本就是:3、Xgboost目标函数4、Xgboost优点:5、其他细节6、常见的问题:小结:所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复