XGBOOST常见问题以及面试题④

高频面试题目

  • 手推XGB
  • XGB与GBDT、随机森林等模型相比,有什么优缺点?
  • XGB为什么可以并行训练?
  • XGB用二阶泰勒展开的优势在哪?
  • XGB为了防止过拟合,进行了哪些设计?
  • XGB如何处理缺失值?
  • XGB如何分裂一个结点?如何选择特征?
  • XGB中一颗树停止生长的条件有哪些?
  • XGB叶子结点的权重有什么含义?如何计算?
  • 训练一个XGB模型,经历了哪些过程?调参步骤是什么?
  • XGB如何给特征评分?

答案

0、简单介绍XGBOOST算法

说到xgboost需要首先说一说GBDT,它是一种基于boosting增强策略的加法模型,训练时候采用前向分布算法进行贪婪学习,每次学习都是一颗cart树,来拟合之前t-1棵树预测结果与训练样本真实值的残差。

xgboost是对gbdt进行来一系列的优化,比如损失函数进行了二阶展开,目标函数加入正则项,支持并行和默认缺失值处理等,在可扩展性和训练速度上有了巨大提升,但是核心思想没有大的变化。

1、 手推XGB

2、 XGB与GBDT、随机森林等模型相比,有什么优缺点?

  • XGB和随机森林

  • 1)随机森林采用的bagging思想,而GBDT采用的boosting思想。这两种方法都是Bootstrap思想的应用,Bootstrap是一种有放回的抽样方法思想。虽然都是有放回的抽样,但二者的区别在于:Bagging采用有放回的均匀取样,而Boosting根据错误率来取样(Boosting初始化时对每一个训练样例赋相等的权重1/n,然后用该算法对训练集训练t轮,每次训练后,对训练失败的样例赋以较大的权重),因此Boosting的分类精度要优于Bagging。Bagging的训练集的选择是随机的,各训练集之间相互独立,弱分类器可并行,而Boosting的训练集的选择与前一轮的学习结果有关,是串行的。

  • 2)组成随机森林的树可以是分类树,也可以是回归树;而GBDT只能由回归树组成。

  • 3)组成随机森林的树可以并行生成;而GBDT只能是串行生成。

  • 4)对于最终的输出结果而言,随机森林采用多数投票等;而GBDT则是将所有结果累加起来,或者加权累加起来。

  • 5)随机森林对异常值不敏感;GBDT对异常值非常敏感。

  • 6)随机森林对训练集一视同仁;GBDT是基于权值的弱分类器的集成。

  • 7)随机森林是通过减少模型方差提高性能;GBDT是通过减少模型偏差提高性能。

  • XGB和GBDT

  • GBDT是机器学习算法,XGBoost是该算法的工程实现

  • 基分类器 传统的GBDT采用CART作为基分类器,xgboost的基分类器不仅支持cart树,还支持线性分类器,此时的xgboost相当于带L1和L2正则项的逻辑回归(分类问题)或者线性回归(回归问题)

  • 导数信息 GBDT在模型训练时只使用了代价函数的一阶导数信息, xgboost对损失函数(代价函数)做了二阶泰勒展开,可以同时使用一阶和二阶导数,gbdt只用了一阶导数,并且xgboost还支持自定义损失函数,只有损失函数一阶,二阶可导。

  • 正则项 在使用CART作为基分类器时,XGBoost在目标函数中加入了正则项来控制模型的复杂度,有利于防止过拟合,从而提高模型的泛化能力,这是gbdt中没有的
    列抽样 传统的GBDT在每轮迭代时使用全部的数据,XGBoost则采用了与随机森林相似的策略,支持对数据进行采样,xgboost支持列抽样,即特征抽样,与随机森林类似,用于防止过拟合

  • 缺失值处理 传统的GBDT没有设计对缺失值进行处理,XGBoost能够自动学习出缺失值的处理策略。对树中的非叶子结点,xgboost在训练过程中会自动学习出它的默认分裂方向,如果测试样本的该特征的特征值缺失,将会划入默认分支中去。

  • 并行化 注意不是tree维度的并行(boosting策略类的加法模型都做不到tree级别的并行),而是特征维度的并行,xgboost预先将每个特征按特征值排好序,存储为block结构,分裂结点时,可以采用多线程并行查找每个特征的最佳分裂点,从而提升训练速度

  • 处理不平衡 在计算损失函数时,考虑不平衡因素,加权损失。


“你能讲一下Xgboost和GBDT的区别吗?”另一种回答方式

  • “Xgboost是GBDT算法的一种很好的工程实现,并且在算法上做了一些优化,主要的优化在一下几点。首先Xgboost采用二阶泰勒展开拟合损失函数,可以加速模型收敛;然后加了一个衰减因子,相当于一个学习率,可以减少加进来的树对于原模型的影响,让树的数量变得更多;其次是在原GBDT模型上加了个正则项,对于树的叶子节点的权重做了一个约束;还有增加了在随机森林上常用的col subsample的策略;然后最大的地方在于不需要遍历所有可能的分裂点了,它提出了一种估计分裂点的算法。在工程上做了一个算法的并发实现,具体我并不了解如何实现的”

3、XGBOOST为什么可以并行训练?

  • 不是tree维度的并行(boosting策略类的加法模型都做不到tree级别的并行,每棵树训练前需要等待前面每棵树训练完成才能开始新一轮的训练)
  • 而是特征维度的并行,xgboost预先将每个特征按特征值排好序,存储为block结构,分裂结点时,可以采用多线程并行查找每个特征(一个特征一个block块)的最佳分裂点,从而提升训练速度

4、为什么XGBoost要用泰勒二阶展开,优势在哪里?

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

5、xgboost防止过拟合的方法

xgboost在设计之初,为了防止过拟合就采取了很多的优化,具体如下:

  • 目标函数加入正则项,叶子结点个数+叶子结点权值的l2正则化
  • 列抽样,训练时只用一部分特征,(不考虑剩余的block块即可)
  • 子采样,下采样 每轮计算可以不采用所有的样本,使得算法更保守
  • shrinkage ,可以叫做学习率或者步长,为了给后面的训练留出更多的学习空间

6、xgboost如何处理缺失值

xgboost模型的一个优点就是允许存在缺失值,对缺失值的处理如下:

  • 在特征k上选择最佳的 分裂点时,不会对该列特征 missing的样本进行遍历,而只是对该列特征值为 non-missing的样本进行对应的特征值遍历,通过这个技巧减少了为稀疏离散特征寻找 分裂点的时间开销

  • 逻辑实现上,为了保证完备性,会将该特征值missing的样本分别分配到左结点和右结点上去,两种情况都计算一遍后,选择分裂后增加最大的那个方向(左方向或者右方向),作为预测时特征值缺失样本的默认分支方向。

  • 如果在训练时没有缺失值而在预测时有出现缺失值,那么会自动将缺失值的划分方向放到右结点上去。

“对缺失值是怎么处理的?”另一种回答方式

  • “在普通的GBDT策略中,对于缺失值的方法是先手动对缺失值进行填充,然后当做有值的特征进行处理,但是这样人工填充会影响数据分布,而且没有什么理论依据。而Xgboost采取的策略是先不处理那些值缺失的样本,先依据有值的特征计算特征的分割点,然后在遍历每个分割点的时候,尝试将缺失样本划入左子树和右子树,选择使损失最优的情况。”

7、XGB如何分裂一个结点?如何选择特征?

8、XGB中一颗树停止生长的条件有哪些?

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

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

9、XGB叶子结点的权重有什么含义?如何计算?

10、训练一个XGB模型,经历了哪些过程?调参步骤是什么?

11、XGB如何给特征评分?


补充:

1. 树该怎么长

很有意思的一个事是,我们从头到尾了解了xgboost如何优化、如何计算,但树到底长啥样,我们却一直没看到。很显然,一棵树的生成是由一个节点一分为二,然后不断分裂最终形成为整棵树。那么树怎么分裂的就成为了接下来我们要探讨的关键。对于一个叶子节点如何进行分裂,XGBoost作者在其原始论文中给出了一种分裂节点的方法:枚举所有不同树结构的贪心法

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

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

在计算损失函数时,考虑不平衡因素,加权损失。

2、XGBOOST为什么快?

  • 分块并行,一个特征一个block块,训练前每个特征按照特征值的排序,存储为block块结构,后面查找特征分割点时可以重复使用,并且支持并且查找每个特征的分割点
  • 候选分位点,每个特征采用常数个分位点作为候选分割点,这里注意有加权,不是直接按从小到大的分位点,而是按照权值的分位点,权值大小为二阶导。(因为可能不同的特征取值都对应同一个预测值,同一个预测值对应同一个损失,同一个二阶导,
  • cpu cache命中,使用存储预取的方法,对每个线程分配一个连续的buffer,读取每个block中样本的梯度,并存入连续的buffer 中
  • block 处理优化,block预先放入内存中,block按列进行解压缩,将block划分导不同的硬盘提高吞吐(这条不太懂)

3、xgboost的叶子结点的权值如何计算出来

参考上一篇xgboost
在这里插入图片描述

4、有测试过Xgboost和GBDT的效果区别吗?你认为在你的项目上是什么导致原因导致了这个区别”

“是的,我们有试过,Xgboost的精度要比GBDT高而且效率也要更高。我认为精度高的最大原因是大部分的CTR特征中,我们会将一些稀疏的离散特征转化为连续特征,会产生很多含有缺失值的稀疏列,导致原始GBDT算法效果不好。而Xgboost会对缺失值做一个特殊的处理。在单机的效率高是因为建树时采用了基于分位数的分割点估计算法”

5、你知道在什么情况下应该使用Onehot呢?”

“对于无序特征来说需要做onehot,实践中发现在线性模型中将连续值特征离散化成0/1型特征效果会更好(线性模型拟合连续特征能力弱,需要将连续特征离散化 成one hot形式提升模型的拟合能力)。所以对于稠密的类别型特征,可以对离散特征做一个OneHot变化,对于稀疏的离散特征采用onehot会导致维度爆炸以及变换后更加稀疏的特征,最好还是采用bin count或者embedding的方法去处理”

会继续更新

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值