Xgboost

1.Bagging vs Boosting

共同点:都是由很多弱(weak)分类器来构成的

 Bagging是有很多weak learner组成的,每个weak learner因为是过拟合,所以整个变得很弱。

2.Xgboost

(1) 引言

提升树

 

 

残差=真实值-预测值

 接下来再训练第二个模型,让残差再小一点,这是一个持续的训练过程

 

这种训练方式是基于残差训练的,是一个一个训练的,没有投票的方式,每个模型都参与到训练中,是一种加的方式。

 这与随机森林的训练方式有很大的不一样,随机森林的训练方式是同时训练多个模型,预测的时候,可以通过一些加权平均的方式,投票的方式。

 (2)为什么XGBoost这么火?

  • 算法可以并行,训练效率高
  • 比起其他算法,实际效果好
  • 由于可控参数(超参数)多,可以灵活调整

 XGBoost的目标函数不是连续的,不能用梯度下降法(SGD)优化

(3)XGBoost目标函数的构建

 

 

 

 

 在XGBoost中评估树的复杂度有两个维度:(通过调节这些参数控制复杂度)

  • 节点个数
  • 节点的值

 当我去训练第K棵树的时候,前面的k-1棵树是已知的,

yi表示目前为止的累加值,i表示第i个样本

 为什么hi,gi代表着残差信息呢?

因为可以看到公式,表示的是前k-1棵树的信息

简要说一下Adaboost,XGBoost的区别?

现在Adaboost用的不多了,Adaboost是对分错的样本进行权重提升,再进行下一轮的训练,XGBoost是基于残差的训练。如第一轮训练,x1,x2,...x100,中x100被分类错误,在第二轮训练时候,就将w100提升。

现在目标函数简化成求fk(xi)和树的复杂度Ω(fk)

  • 求fk(xi)

  • 树的复杂度Ω(fk)

(4)打分函数的计算

 上面红色方框的可以用下面的式子推出

Obj代表了当我们指定一个树的结构的时候,我们在目标上面最多减少多少。我们可以把它叫做结构分数(structure score)

 条件是,我已知树的形状的,马上就可以算出这棵树的最优解,我要从这1万棵树中寻找obj最小的那棵树。

我们的最终目标是寻找第k棵树的最小的目标函数,即寻找最好的树的形状,但是树的形状有可能是下图的那么多形状,怎么样找到最好的树的形状,这就需要研究最好的分裂节点。对于这些树的形状假设已知了,我就可以算出这棵树的最优解。

(5)分裂节点(树的生长)

很有意思的一个事是,我们从头到尾了解了xgboost如何优化、如何计算,但树到底长啥样,我们却一直没看到。很显然,一棵树的生成是由一个节点一分为二,然后不断分裂最终形成为整棵树。那么树怎么分裂的就成为了接下来我们要探讨的关键。决策树中,就是把熵entropy,换成这里的obj就行了。

 接下来就是寻找那棵树

用贪心算法,每次要选择什么特征来分割呢,就是让这个值最大化的那个特征来分割,因为每次只关注当前那个节点,在这个节点上选择最好的特征,什么叫最好的特征,让这个值最大的那个特征,就是最好的特征。

当选特征1的效果,是体现在这个地方的。

XGBoost作者在其原始论文中给出了一种分裂节点的方法:枚举所有不同树结构的贪心法

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

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

如下面的决策树,通过特征1将这些样本进行拆分,之后再对{1,3,4},{2,5,6,7,8}进行拆解

那么 选择特征的依据是什么?

信息增益,让信息增益的值变大,让不确定性(熵Entropy)变小,特征1的score:原(不确定性)- 之后(不确定性),就是将基于特征1,特征2的信息增益计算出来,选择信息增益大的作为拆分的特征

(6)如何停止树的循环生成

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

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

 3.总结Xgboost的核心思想

  • 不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数,去拟合上次预测的残差。

                                

 

注:w_q(x)为叶子节点q的分数,对应了所有K棵回归树(regression tree)的集合,而f(x)为其中一棵回归树。

  • 当我们训练完成得到k棵树,我们要预测一个样本的分数,其实就是根据这个样本的特征,在每棵树中会落到对应的一个叶子节点,每个叶子节点就对应一个分数
  • 最后只需要将每棵树对应的分数加起来就是该样本的预测值。

举个例子,我们要预测一家人对电子游戏的喜好程度,考虑到年轻和年老相比,年轻更可能喜欢电子游戏,以及男性和女性相比,男性更喜欢电子游戏,故先根据年龄大小区分小孩和大人,然后再通过性别区分开是男是女,逐一给各人在电子游戏喜好程度上打分,如下图所示。

                       

 

 就这样,训练出了2棵树tree1和tree2,类似之前gbdt的原理,两棵树的结论累加起来便是最终的结论,所以小孩的预测分数就是两棵树中小孩(一个样本)所落到的结点的分数相加:2 + 0.9 = 2.9。爷爷的预测分数同理:-1 + (-0.9)= -1.9。具体如下图所示

                                   

 

4.XGBoost与GBDT有什么不同

除了算法上与传统的GBDT有一些不同外,XGBoost还在工程实现上做了大量的优化。总的来说,两者之间的区别和联系可以总结成以下几个方面。

  • GBDT是机器学习算法,XGBoost是该算法的工程实现。
  • 在使用CART作为基分类器时,XGBoost显式地加入了正则项来控制模 型的复杂度,有利于防止过拟合,从而提高模型的泛化能力。
  • GBDT在模型训练时只使用了代价函数的一阶导数信息,XGBoost对代 价函数进行二阶泰勒展开,可以同时使用一阶和二阶导数
  • 传统的GBDT采用CART作为基分类器,XGBoost支持多种类型的基分类 器,比如线性分类器。
  • 传统的GBDT在每轮迭代时使用全部的数据,XGBoost则采用了与随机 森林相似的策略,支持对数据进行采样。
  • 传统的GBDT没有设计对缺失值进行处理,XGBoost能够自动学习出缺 失值的处理策略。

插一句,一般的目标函数都包含下面两项

                                                 

 

 其中,误差/损失函数鼓励我们的模型尽量去拟合训练数据,使得最后的模型会有比较少的 bias。而正则化项则鼓励更加简单的模型。因为当模型简单之后,有限数据拟合出来结果的随机性比较小,不容易过拟合,使得最后模型的预测更加稳定。

5.为什么XGBoost要用泰勒展开,优势在哪里?

XGBoost使用了一阶和二阶偏导, 二阶导数有利于梯度下降的更快更准. 使用泰勒展开取得函数做自变量的二阶导数形式, 可以在不选定损失函数具体形式的情况下, 仅仅依靠输入数据的值就可以进行叶子分裂优化计算, 本质上也就把损失函数的选取和模型算法优化/参数选择分开了. 这种去耦合增加了XGBoost的适用性, 使得它按需选取损失函数, 可以用于分类, 也可以用于回归。

参考文章:

https://blog.csdn.net/v_JULY_v/article/details/81410574

https://www.cnblogs.com/mantch/p/11164221.html

posted @ 2020-09-03 20:02  GumpYan  阅读(475)  评论(0编辑  收藏  举报