XGBoost是陈天奇等人开发的一个开源机器学习项目,高效地实现了GBDT算法并进行了算法和工程上的许多改进,被普遍应用在Kaggle竞赛及其余许多机器学习竞赛中并取得了不错的成绩。git
说到XGBoost,不得不提GBDT(Gradient Boosting Decision Tree)。由于XGBoost本质上仍是一个GBDT,可是力争把速度和效率发挥到极致,因此叫X (Extreme) GBoosted。包括前面说过,二者都是boosting方法。github
关于GBDT,这里再也不提,能够查看我前一篇的介绍,点此跳转。面试
先来举个例子,咱们要预测一家人对电子游戏的喜爱程度,考虑到年轻和年老相比,年轻更可能喜欢电子游戏,以及男性和女性相比,男性更喜欢电子游戏,故先根据年龄大小区分小孩和大人,而后再经过性别区分开是男是女,逐一给各人在电子游戏喜爱程度上打分,以下图所示。算法
就这样,训练出了2棵树tree1和tree2,相似以前gbdt的原理,两棵树的结论累加起来即是最终的结论,因此小孩的预测分数就是两棵树中小孩所落到的结点的分数相加:2 + 0.9 = 2.9。爷爷的预测分数同理:-1 + (-0.9)= -1.9。具体以下图所示:机器学习
恩,你可能要拍案而起了,惊呼,这不是跟上文介绍的GBDT乃殊途同归么?函数
事实上,若是不考虑工程实现、解决问题上的一些差别,XGBoost与GBDT比较大的不一样就是目标函数的定义。XGBoost的目标函数以下图所示:学习
其中:优化
看到这里可能有些读者会头晕了,这么多公式,我在这里只作一个简要式的讲解,具体的算法细节和公式求解请查看这篇博文,讲得很仔细:通俗理解kaggle比赛大杀器xgboost.net
XGBoost的核心算法思想不难,基本就是:设计
显然,咱们的目标是要使得树群的预测值尽可能接近真实值
,并且有尽可能大的泛化能力。相似以前GBDT的套路,XGBoost也是须要将多棵树的得分累加获得最终的预测得分(每一次迭代,都在现有树的基础上,增长一棵树去拟合前面树的预测结果与真实值之间的残差)。
那接下来,咱们如何选择每一轮加入什么 f 呢?答案是很是直接的,选取一个 f 来使得咱们的目标函数尽可能最大地下降。这里 f 可使用泰勒展开公式近似。
实质是把样本分配到叶子结点会对应一个obj,优化过程就是obj优化。也就是分裂节点到叶子不一样的组合,不一样的组合对应不一样obj,全部的优化围绕这个思想展开。到目前为止咱们讨论了目标函数中的第一个部分:训练偏差。接下来咱们讨论目标函数的第二个部分:正则项,即如何定义树的复杂度。
XGBoost对树的复杂度包含了两个部分:
咱们再来看一下XGBoost的目标函数(损失函数揭示训练偏差 + 正则化定义复杂度):
正则化公式也就是目标函数的后半部分,对于上式而言,是整个累加模型的输出,正则化项∑kΩ(ft)是则表示树的复杂度的函数,值越小复杂度越低,泛化能力越强。
颇有意思的一个事是,咱们从头至尾了解了xgboost如何优化、如何计算,但树到底长啥样,咱们却一直没看到。很显然,一棵树的生成是由一个节点一分为二,而后不断分裂最终造成为整棵树。那么树怎么分裂的就成为了接下来咱们要探讨的关键。对于一个叶子节点如何进行分裂,XGBoost做者在其原始论文中给出了一种分裂节点的方法:枚举全部不一样树结构的贪心法
不断地枚举不一样树的结构,而后利用打分函数来寻找出一个最优结构的树,接着加入到模型中,不断重复这样的操做。这个寻找的过程使用的就是贪心算法。选择一个feature分裂,计算loss function最小值,而后再选一个feature分裂,又获得一个loss function最小值,你枚举完,找一个效果最好的,把树给分裂,就获得了小树苗。
总而言之,XGBoost使用了和CART回归树同样的想法,利用贪婪算法,遍历全部特征的全部特征划分点,不一样的是使用的目标函数不同。具体作法就是分裂后的目标函数值比单子叶子节点的目标函数的增益,同时为了限制树生长过深,还加了个阈值,只有当增益大于该阈值才进行分裂。从而继续分裂,造成一棵树,再造成一棵树,每次在上一次的预测基础上取最优进一步分裂/建树。
凡是这种循环迭代的方式一定有中止条件,何时中止呢?简言之,设置树的最大深度、当样本权重和小于设定阈值时中止生长以防止过拟合。具体而言,则
除了算法上与传统的GBDT有一些不一样外,XGBoost还在工程实现上作了大量的优化。总的来讲,二者之间的区别和联系能够总结成如下几个方面。
XGBoost使用了一阶和二阶偏导, 二阶导数有利于梯度降低的更快更准. 使用泰勒展开取得函数作自变量的二阶导数形式, 能够在不选定损失函数具体形式的状况下, 仅仅依靠输入数据的值就能够进行叶子分裂优化计算, 本质上也就把损失函数的选取和模型算法优化/参数选择分开了. 这种去耦合增长了XGBoost的适用性, 使得它按需选取损失函数, 能够用于分类, 也能够用于回归。
GitHub:点击进入
做者:@mantchs
GitHub:github.com/NLP-LOVE/ML…