XGboost

一、GBDT简述

  GBDT:英文全称:Gradient Boosting Decision Tree 。GBDT中的树都是回归树。GBDT的主要是思想是每次把上一棵树的输出和label的残差作为下一棵树的label进行拟合,前面的树做不好的地方后面的补上,不断把拟合后的预测的残差值叠加上去,进行梯度的提升。一句话解释:以决策树为基模型(base model),以损失函数的负梯度为学习目标的boosting集成模型。

  这句话有三个概念:决策树,损失函数的负梯度,boosting

  第一个基本概念的解释(决策树):

  决策树主流有三类ID3,C4.5,CRAT树。GBDT的基模型是CART树。

  ID3使用信息增益作为分裂点选择

  C4.5使用信息增益比作为分裂点选择

  CART树使用基尼系数作为分裂点选择

  第二个基本概念的解释(损失函数的负梯度):

  损失函数的负梯度本身是优化算法中特征权重的更新方向和大小。为什么GDBT的基模型要去拟合损失负梯度,而不是拟合y,或者拟合y- ^y?

  1.GBDT整体上是拟合y的,但是每个基模型不是去拟合y,如果是的话就是bagging集成模型,比如随机森林

  2.GBDT的基模型为什么不是拟合残差。将下式一阶展开,可以发现若移动负梯度是最小化损失函数的方向。

             

  如果不考虑正则项,并且使用平方误差,拟合残差是没有问题的。在有正则项的情况下就不再是损失函数最小了。

  第三个基本概念的解释(boosting):

  集成模型是把若干个基模型(也称“弱学习器”)按照一定的策略组合起来,发挥1+1>2的作用。集成模型主要有三种集成策略,bagging, stacking,boosting。

  Bagging集成:各个基模型训练相互独立。在回归问题中,会把各个基模型的预测取平均。在分类问题中,则使用投票策略。比如随机森林就是使用bagging模型。

  stacking集成:stacking的基模型之间也是相互独立。与bagging不同的是,stacking会把基模型预测结果作为第二层模型的输入,重新预测的结果作为最终的输出。stacking的基模型在工程实践中会选择强模型。比如xgboost。而且基模型一般会选择不同类型的强模型。第二层一般会选择线性回归或者逻辑斯特回归。理论上看,stacking模型已经证明其集成结果应该“渐进等价”第一层中的最优子模型。stacking的结果有点类似于两层神经网络,只不过第一层神经元都是强模型。

  boosting集成:与前两种集成模型不同的是,boosting的基模型不是相互独立的,是相关的。(不是并联,是串联)。Boosting 是一种集成技术,另外boosting模型的基模型也是弱模型。其中添加新模型以纠正现有模型所造成的错误。模型按顺序添加,直到无法进行进一步改进。一个流行的例子是AdaBoost 算法,它对难以预测的数据点进行加权。梯度提升是一种创建新模型的方法,用于预测先前模型的残差或误差,然后将它们相加以进行最终预测。之所以称为梯度提升,是因为它使用梯度下降算法来最小化添加新模型时的损失。xgboost支持回归和分类预测建模问题。boosting比较经典的三个算法:提升树模型(adaboost),梯度提升树模型(gbdt),xgboost模型。

二、Xgboost简述

  Xgboost可以拆成两部分X +gboost。gboost就是gbdt。x就是牛逼。要理解xgboost,gbdt是基础。X体现在1.损失函数二阶展开,2.快速查找分裂点,3.强大的防止过拟合能力,4.对缺失值的处理

  Xgboost与GBDT最大的区别就是树的生成方式不同,加快了树的生成过程,以生成最优树。XGBoost 库实现了梯度提升决策树算法,该算法有很多不同的名称,例如梯度提升、多重加性回归树、随机梯度提升或梯度提升机。

  1.损失函数二阶展开:

  XGboost与GBDT都是每一步都只优化当前模型,然后将所有模型加起来。传统GBDT在优化时只用到一阶导数信息,xgboost为了加速算法的计算对代价函数进行了二阶泰勒展开,同时拟合一阶误差和二阶误差有利于提升精度。顺便提一下,xgboost工具支持自定义代价函数,只要函数可一阶和二阶求导。 —对损失函数做了改进(泰勒展开,一阶信息g和二阶信息h)

  2.快速查找分裂点:
  对于树模型来说,算法优化其实就是指导树的分裂。xgb算法的思路与CART一样,都是遍历所有特征,选择收益最高的分裂点进行分裂。

  (1):精确贪婪算法

  这种算法就是详细地遍历每个特征,然后遍历每个特征可能的取值,搜索出最优的分裂特征以及该特征的分裂值

  (2):近似算法

  在很多种情况下,每个特征的取值(离散的取值)可能有成千上万个,遍历每个取值的话时间开销会非常的大。很多时候,特征分裂的取值稍微差了一点也不会有太大的影响。为了对整个分裂过程进行加速,我们可以对特征值进行分箱。比如将样本种某个特征是连续值,取值有几万个,我们可以将其分箱为几十个,然后遍历每个特征的取值的时候,我们只需要遍历每个箱。这样的话极快地减少了计算的次数。关于分箱的方法在xgb的论文种提及了两种:global和local两种。global是在所有树生成开始之前,将需要的特征分好箱。整个训练过程每个特征都只需要分一次。local是在每次进行特征值遍历的时候进行分箱,一个训练过程会分裂很多很多次。

  (3):加权分位数

  这一步是对上一步近似算法补充,上一步我们说到对特征分箱,但是怎么对特征分箱?常用的方法是按照样本分布,比如100个样本我要分5箱,那么我可能会使得每箱中有20个样本,这样我就可以将样本排序后,在第20,40,60,80处对样本进行分箱。但是在xgboost中采用一种加权分为的分箱方法。将hi作为权重,每个区间中hi的权重相等。

  3.强大的防止过拟合能力:

  xgboost与GBDT相比还有一个正则项,用于控制模型的复杂度。其中T为树f的叶节点的个数,wj为第j个叶节点的权重。很容易理解叶节点越少越不容易过拟合,但是为什么w叶节点的取值也可以作为正则项呢?(作者)的理解是:

  xgboost是一个加法模型,每个样本最后的取值是每个树的值加起来。比如某个样本在n棵树中处于叶节点的取值分别为:wi。那么该样本最后的取值为:∑wi(这么一看的话和逻辑输入特征为0-1的逻辑回归还是很像的)。我们会倾向于该样本在每个树中的取值尽可能的小一些,那样样本最后的取值受某一个树的影响就会变小,更不容易过拟合。

                    
  4.对缺失值的处理(稀疏感知):

  在数据中经常会出现这些现象:1:缺失值,2:为0的值太多,3:特征one-hot(其实也是导致为0的值太多)。XGB中允许缺失值存在,采用稀疏感知策略来同时处理这类问题,将缺失值和稀疏0值等同视作缺失值,"绑定"在一起,节点分裂的时候不会遍历这些节点,减少计算,分配样本时,缺失的样本同时分到左右子树,计算哪边的增益大就自动分到哪边去。但在测试时如果遇到缺失值,会分到右子树。

三、优缺点

优点(快速高效可容错)

  • 支持线性分类器(相当于引入L1 L2正则惩罚项的LR和线性回归,目标函数公式=误差平方和+正则项,似LR)
  • 代价函数用了二阶Talor展开,引入一阶导和二阶导,提高模型拟和的速度(损失函数:一个样本的误差;代价函数:整个训练集上所有样本误差的平均;目标函数:代价函数 + 正则化项)
  • 可以给缺失值自动划分方向;
  • 同RF,支持样本(行)随机抽取,也支持特征(列)随机抽取,降低运算,防过拟合;
  • 代价函数引入正则化项,控制模型(树)复杂度,
    正则化项包含全部叶子节点个数,每个叶子节点得分的L2模的平方和(代表叶子节点权重的影响)
    从贝叶斯(先验累积思想)方差角度考虑,正则降低了模型的方差,防过拟和;
  • 每次迭代后为叶子分配结合学习速率,减低每棵树权重,减少每棵树影响,灵活调整后面的学习空间;
  • 支持并行,不是树并行,是把特征值先预排序,存起来,可以重复并行使用计算分裂点;
  • 分裂依据分开后与未分前的差值增益,不用每个节点排序算增益,减少计算量,可以并行计算;
  • 可以引入阈值限制树分裂,控制树的规模。

缺点:

  • 容易过拟合;
  • 调参困难。

sklearn参数

  • learning_rate:学习率
  • n_estimators:多少棵树
  • max_depth=5:树最大深度
  • min_child_weight:最小权重系数
  • gamma=0:惩罚系数(力度)
  • lambda:正则化
  • alpha:正则化
  • subsample:随机选样本的比例
  • colsample_bytree:随机选特征
  • objective = 'binary:logistic':损失函数loss function,求这个函数的一阶二阶导
  • scale_pos_weight:要不要指定一个均衡的树
  • seed=7 #随机种子,每次复现都是一样的





参考链接:https://www.jianshu.com/p/99d8f56ea536
posted @ 2022-07-16 19:08  hungry_J  阅读(30)  评论(0)    收藏  举报