XGboost高频面试
- 1. 简单介绍一下XGBoost
- 2. XGBoost与GBDT有什么不同
- 3. XGBoost为什么使用泰勒二阶展开
- 4. XGBoost为什么可以并行训练
- 5. XGBoost为什么快
- 6. XGBoost防止过拟合的方法
- 8. XGBoost中叶子结点的权重如何计算出来
- 9. XGBoost中的一棵树的停止生长条件
- 10. RF和GBDT的区别
- 11. XGBoost如何处理不平衡数据
- 12. 比较LR和GBDT,说说什么情景下GBDT不如LR
- 13. XGBoost中如何对树进行剪枝
- 14. XGBoost如何选择最佳分裂点?
- 15. XGBoost的Scalable性如何体现
- 16. XGBoost如何评价特征的重要性
- 17. XGBooost参数调优的一般步骤
- 18. XGBoost模型如果过拟合了怎么解决
- 19.为什么XGBoost相比某些模型对缺失值不敏感
- 20. LightGBM比XGBoost的优点
1. 简单介绍一下XGBoost
- XGBoost的GBDT优化版,比如损失函数进行了二阶泰勒展开、目标函数加入正则项、支持并行和默认缺失值处理等,在可扩展性和训练速度上有了巨大的提升,但其核心思想是一样的。
- GBDT是一种基于boosting增强策略模型,训练的时候采用前向分布算法进行贪婪的学习,每次迭代都学习一棵CART树来拟合之前 t-1 棵树的预测结果与训练样本真实值的残差。
2. XGBoost与GBDT有什么不同
- 基分类器:XGBoost的基分类器不仅支持CART决策树,还支持线性分类器,此时XGBoost相当于带L1和L2正则化项的Logistic回归(分类问题)或者线性回归(回归问题)。
- 导数信息:XGBoost对损失函数做了二阶泰勒展开,GBDT只用了一阶导数信息,并且XGBoost还支持自定义损失函数,只要损失函数一阶、二阶可导。
- 正则项:XGBoost的目标函数加了正则项, 相当于预剪枝,使得学习出来的模型更加不容易过拟合。
- 列抽样:XGBoost支持列采样,与随机森林类似,用于防止过拟合。
- 缺失值处理:对树中的每个非叶子结点,XGBoost可以自动学习出它的默认分裂方向。如果某个样本该特征值缺失,会将其划入默认分支。
- 并行化:注意不是tree维度的并行,而是特征维度的并行。XGBoost预先将每个特征按特征值排好序,存储为块结构,分裂结点时可以采用多线程并行查找每个特征的最佳分割点,极大提升训练速度。
3. XGBoost为什么使用泰勒二阶展开
- 精准性:相对于GBDT的一阶泰勒展开,XGBoost采用二阶泰勒展开,可以更精准的逼近真实的损失函数
- 可扩展性:损失函数支持自定义,只需要新的损失函数二阶可导。
4. XGBoost为什么可以并行训练
- XGBoost的并行,并不是说每棵树可以并行训练,XGB本质上仍然采用boosting思想,每棵树训练前需要等前面的树训练完成才能开始训练。
- XGBoost的并行,指的是特征维度的并行:在训练之前,每个特征按特征值对样本进行预排序,并存储为Block结构,在后面查找特征分割点时可以重复使用,而且特征已经被存储为一个个block结构,那么在寻找每个特征的最佳分割点时,可以利用多线程对每个block并行计算。
5. XGBoost为什么快
- 分块并行:训练前每个特征按特征值进行排序并存储为Block结构,后面查找特征分割点时重复使用,并且支持并行查找每个特征的分割点
- 候选分位点:每个特征采用常数个分位点作为候选分割点
- CPU cache 命中优化: 使用缓存预取的方法,对每个线程分配一个连续的buffer,读取每个block中样本的梯度信息并存入连续的Buffer中。
- Block 处理优化:Block预先放入内存;Block按列进行解压缩;将Block划分到不同硬盘来提高吞吐
6. XGBoost防止过拟合的方法
XGBoost在设计时,为了防止过拟合做了很多优化,具体如下:
- 目标函数添加正则项:叶子节点个数+叶子节点权重的L2正则化
- 列抽样:训练的时候只用一部分特征(不考虑剩余的block块即可)
- 子采样:每轮计算可以不使用全部样本,使算法更加保守
- shrinkage: 可以叫学习率或步长,为了给后面的训练留出更多的学习空间
8. XGBoost中叶子结点的权重如何计算出来
XGBoost目标函数最终推导形式如下:
利用一元二次函数求最值的知识,当目标函数达到最小值Obj时,每个叶子结点的权重为wj。
具体公式如下:
9. XGBoost中的一棵树的停止生长条件
- 当新引入的一次分裂所带来的增益Gain<0时,放弃当前的分裂。这是训练损失和模型结构复杂度的博弈过程。
- 当树达到最大深度时,停止建树,因为树的深度太深容易出现过拟合,这里需要设置一个超参数max_depth。
- 当引入一次分裂后,重新计算新生成的左、右两个叶子结点的样本权重和。如果任一个叶子结点的样本权重低于某一个阈值,也会放弃此次分裂。这涉及到一个超参数:最小样本权重和,是指如果一个叶子节点包含的样本数量太少也会放弃分裂,防止树分的太细。
10. RF和GBDT的区别
- RF属于bagging思想,而GBDT是boosting思想
- 偏差-方差权衡:RF不断的降低模型的方差,而GBDT不断的降低模型的偏差
- 训练样本:RF每次迭代的样本是从全部训练集中有放回抽样形成的,而GBDT每次使用全部样本
- 并行性:RF的树可以并行生成,而GBDT只能顺序生成(需要等上一棵树完全生成)
- 最终结果:RF最终是多棵树进行多数表决(回归问题是取平均),而GBDT是加权融合
- 数据敏感性:RF对异常值不敏感,而GBDT对异常值比较敏感
- 泛化能力:RF不易过拟合,而GBDT容易过拟合
11. XGBoost如何处理不平衡数据
对于不平衡的数据集,例如用户的购买行为,肯定是极其不平衡的,这对XGBoost的训练有很大的影响,XGBoost有两种自带的方法来解决:
- 第一种,使用AUC时,可以通过设置scale_pos_weight来平衡正样本和负样本的权重。例如,当正负样本比例为1:10时,scale_pos_weight可以取10;
- 第二种,如果你在意概率(预测得分的合理性),你不能重新平衡数据集(会破坏数据的真实分布),应该设置max_delta_step为一个有限数字来帮助收敛(基模型为LR时有效)。
- 除此之外,还可以通过上采样、下采样、SMOTE算法或者自定义代价函数的方式解决正负样本不平衡的问题。
12. 比较LR和GBDT,说说什么情景下GBDT不如LR
- LR是线性模型,可解释性强,容易并行化,但学习能力有限,需要大量的人工特征工程
- GBDT是非线性模型,具有天然的特征组合优势,特征表达能力强,但是树与树之间无法并行训练,而且树模型很容易过拟合;
- 在高维稀疏特征的场景下,LR的效果一般会比GBDT好。
- 原因如下:带正则化的线性模型比较不容易对稀疏特征过拟合。
13. XGBoost中如何对树进行剪枝
- 在目标函数中增加了正则项:使用叶子结点的数目和叶子结点权重的L2模的平方,控制树的复杂度。
- 在结点分裂时,定义了一个阈值,如果分裂后目标函数的增益小于该阈值,则不分裂。
- 当引入一次分裂后,重新计算新生成的左、右两个叶子结点的样本权重和。如果任一个叶子结点的样本权重低于某一个阈值(最小样本权重和),也会放弃此次分裂。
- XGBoost 先从顶到底建立树直到最大深度,再从底到顶反向检查是否有不满足分裂条件的结点,进行剪枝。
14. XGBoost如何选择最佳分裂点?
- XGBoost在训练前预先将特征按照特征值进行了排序,并存储为block结构,以后在结点分裂时可以重复使用该结构。
- 因此,可以采用特征并行的方法利用多个线程分别计算每个特征的最佳分割点,根据每次分裂后产生的增益,最终选择增益最大的那个特征的特征值作为最佳分裂点。
- 如果在计算每个特征的最佳分割点时,对每个样本都进行遍历,计算复杂度会很大,这种全局扫描的方法并不适用大数据的场景
- XGBoost还提供了一种直方图近似算法,对特征排序后仅选择常数个候选分裂位置作为候选分裂点,极大提升了结点分裂时的计算效率。
15. XGBoost的Scalable性如何体现
- 基分类器的scalability:弱分类器可以支持CART决策树,也可以支持LR和Linear。
- 目标函数的scalability:支持自定义loss function,只需要其一阶、二阶可导。有这个特性是因为泰勒二阶展开,得到通用的目标函数形式。
- 学习方法的scalability:Block结构支持并行化,支持 Out-of-core计算。
16. XGBoost如何评价特征的重要性
- weight :该特征在所有树中被用作分割样本的特征的总次数。
- gain :该特征在其出现过的所有树中产生的平均增益。
- cover :该特征在其出现过的所有树中的平均覆盖范围。
17. XGBooost参数调优的一般步骤
- 确定learning rate和estimator的数量
learning rate可以先用0.1,用cv来寻找最优的estimators - max_depth和 min_child_weight
我们调整这两个参数是因为,这两个参数对输出结果的影响很大。我们首先将这两个参数设置为较大的数,然后通过迭代的方式不断修正,缩小范围。
max_depth,每棵子树的最大深度,check from range(3,10,2)。
min_child_weight,子节点的权重阈值,check from range(1,6,2)。
如果一个结点分裂后,它的所有子节点的权重之和都大于该阈值,该叶子节点才可以划分。 - gamma
也称作最小划分损失min_split_loss,check from 0.1 to 0.5,指的是,对于一个叶子节点,当对它采取划分之后,损失函数的降低值的阈值。
如果大于该阈值,则该叶子节点继续划分 - subsample, colsample_bytree
subsample是对训练的采样比例
colsample_bytree是对特征的采样比例
both check from 0.6 to 0.9 - 正则化参数
alpha 是L1正则化系数,try 1e-5, 1e-2, 0.1, 1, 100
lambda 是L2正则化系数 - 降低学习率
降低学习率的同时增加树的数量,通常最后设置学习率为0.01~0.1
18. XGBoost模型如果过拟合了怎么解决
- 第一类参数:用于直接控制模型的复杂度。包括max_depth,min_child_weight,gamma 等参数
- 第二类参数:用于增加随机性,从而使得模型在训练时对于噪音不敏感。包括subsample,colsample_bytree
- 还有就是直接减小learning rate,但需要同时增加estimator 参数。
19.为什么XGBoost相比某些模型对缺失值不敏感
- 对存在缺失值的特征,一般的解决方法是:
离散型变量:用出现次数最多的特征值填充;
连续型变量:用中位数或均值填充; - 一些模型如SVM和KNN,其模型原理中涉及到了对样本距离的度量,如果缺失值处理不当,最终会导致模型预测效果很差。
- 而树模型对缺失值的敏感度低,大部分时候可以在数据缺失时时使用。原因就是,一棵树中每个结点在分裂时,寻找的是某个特征的最佳分裂点(特征值),完全可以不考虑存在特征值缺失的样本,也就是说,如果某些样本缺失的特征值缺失,对寻找最佳分割点的影响不是很大。
- XGBoost对缺失数据有特定的处理方法。
因此,对于有缺失值的数据在经过缺失处理后:
当数据量很小时,优先用朴素贝叶斯
数据量适中或者较大,用树模型,优先XGBoost
数据量较大,也可以用神经网络
避免使用距离度量相关的模型,如KNN和SVM
20. LightGBM比XGBoost的优点
- 分割点查找算法:XGB使用特征预排序算法,LGB使用基于直方图的切分点算法,减少内存占用,提高计算效率
- 支持离散变量:无法直接输入类别型变量,因此需要事先对类别型变量进行编码(例如独热编码),而LightGBM可以直接处理类别型变量。
- 缓存命中率:XGB使用Block结构的一个缺点是取梯度的时候,是通过索引来获取的,而这些梯度的获取顺序是按照特征的大小顺序的,这将导致非连续的内存访问,可能使得CPU cache缓存命中率低,从而影响算法效率。而LGB是基于直方图分裂特征的,梯度信息都存储在一个个bin中,所以访问梯度是连续的,缓存命中率高。
- LightGBM 与 XGboost 的并行策略不同