XGBoost的实现,我以为主要仍是在于对GBDT的改良上。对于GBDT仍是不太熟悉的朋友,请看我这一篇文章《GBDT》。我我的认为这二者区别主要仍是在于细节上,理解了GBDT我认为就差很少等于理解了XGBoost。算法
我重点比较一下XGBoost与GBDT两种算法的不一样:机器学习
最基本的差距就在于XGBoost比GBDT多了两项泰勒展开式。具体这个泰勒展开式是怎么获得的,是对于什么展开的呢?咱们看:
XGBoost算法能够当作是由K棵树组成的加法模型:函数
其中F为全部树组成的函数空间(这里的回归树也就是一个分段函数,不一样分段的不一样取值就构成了一颗树),与通常机器学习算法不一样的是,加法模型不是学习d维空间的权重,而是直接学习决策树的集合。
上述加法模型的目标函数定义为:post
其中Ω表示决策树的复杂度,那么该如何定义树的复杂度呢?好比,能够考虑树的节点数量、树的深度或者叶子节点所对应的分数的L2范数等等。
如何来学习加法模型呢?
解这一优化问题,能够用前向分布算法(forward stagewise algorithm)。有了以前GBDT的基础,咱们知道,加法模型的学习器每次都用函数来拟合上一棵树没有拟合完整的残差,最后将这些残差所有加起来就会获得对于目标完整的预测,这也叫作Boosting。具体地,咱们从一个常量预测开始,每次学习一个新的函数,过程以下:
学习
这个公式看起来仍是比较拗口,想要理解的话建议看我以前的文章《GBDT》,了解了工做模式这公式就好理解了。优化
这就会产生一个新的问题,那个新加入的函数f到底怎么获得的呢?这个原则仍是最小化目标函数。咱们能够将咱们的目标函数写为:3d
咱们再用平方偏差来衡量咱们的损失函数:cdn
其中 就是咱们所谓的残差(residual)。咱们每一次使用平方函数的时候,算法都是为了拟合这个残差。
可能有的朋友对于泰勒公式不是很是熟悉,我将基本的泰勒公式用法写在这:blog
咱们都知道,泰勒级数展开实际上是有无穷多项的,在无穷多项形式里是严格等于,这里咱们暂且只取了前三项省略了后面,因此就是约等于。
那有了泰勒公式的基础,咱们将前面的目标函数变式能够转化为:递归
其中,g与h分别是损失函数的一阶偏导数和二阶偏导数,具体数学形式以下:
咱们也能够将常数项直接去掉,并不会影响,那就使得目标函数是这个样子:
因为要学习的函数仅仅依赖于目标函数,从“去掉常数项的目标函数”能够看出只需为学习任务定义好损失函数,并为每一个训练样本计算出损失函数的一阶导数和二阶导数,经过在训练样本集上最小化目标函数便可求得每步要学习的函数,从而根据加法模型可得最终要学习的模型。
就简单提一句GBDT与XGBoost的区别,明显能够看出,GBDT没有采用二次泰勒展开,这个看似很简单的区别,实际上带来更快的拟合,也大大缩减了生成树的规模,减小了运行时间。
咱们使用损失函数优化是为了不欠拟合,而使用正则化项就是为了不过拟合。正则化项与损失函数共同组成了咱们的目标函数。XGBoost比GBDT多添加了以树复杂度构成的正则化项,也是XGBoost实际表现更为优秀的缘由之一
何为正则化项?正则化项的做用是什么?
咱们都知道,咱们在优化目标函数的时候,老是但愿它更加的“小”,也就是优化通常是最小化的意思。如今咱们若是给目标函数加入一个变量的平方,那么若是这个变量一旦变大,那么目标函数为了“最小化”,必定很不喜欢这个变量变大的事实,选择的时候就会刻意避开会使变量变大的路径。这大概就是正则化的简单解释了。在XGBoost中,咱们是将树的复杂度做为正则项加入,那么优化器在工做的时候,会尽可能不让这个树更加复杂,也就达到咱们的效果。
咱们假设XGBoost决策树的叶子节点个数为T,该决策树是由全部叶子节点对应的值组成的向量w,以及一个把特征向量映射到叶子节点索引(Index)的函数 组成的,咱们将树能够写成:
,咱们也能够将决策树的复杂度定义成正则项:
则目标函数咱们能够写成:
用G与H代换一下原来的式子,咱们就获得了简化后的式子:
假设树的结构是固定的,即函数q(x)为固定的,令目标函数的一阶导数为0,则能够求出叶子节点j对应的值为:
因而在这种条件下,目标函数的值就变成了:
为何要计算这两个值呢?
是为了给你们描述单棵决策树的生成过程:
树结构数量是无穷的,因此实际上咱们不可能枚举全部可能的树结构。一般状况下,咱们采用贪心策略来生成决策树的每一个节点。
咱们来看看这个贪心算法是怎么工做的:
如何计算每次分裂的收益呢?假设当前节点记为C,分裂以后左孩子节点记为L,右孩子节点记为R,则该分裂得到的收益定义为当前节点的目标函数值减去左右两个孩子节点的目标函数值之和:Gain=ObjC-ObjL-ObjR,具体地,根据目标函数值公式可得: