机器学习面试题总结
Posted 耗子来啦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器学习面试题总结相关的知识,希望对你有一定的参考价值。
今天闲着整理了一下GBM的面试题
更多请关注公众号"百面机器学习",有劳东动下手指啦
GBM
简单介绍一下XGBoost
首先需要说一说GBDT,它是一种基于boosting增强策略的加法模型,训练的时候采用前向分布算法进行贪婪的学习,每次迭代都学习一棵CART树来拟合之前 t-1 棵树的预测结果与训练样本真实值的残差。
XGBoost对GBDT进行了一系列优化,比如损失函数进行了二阶泰勒展开、目标函数加入正则项、支持并行和默认缺失值处理等,在可扩展性和训练速度上有了巨大的提升,但其核心思想没有大的变化。 参考:
深入理解XGBoost - 知乎
XGBoost与GBDT的联系和区别有哪些?
(1)GBDT是机器学习算法,XGBoost是该算法的工程实现。
(2)正则项:在使用CART作为基分类器时,XGBoost显式地加入了正则项来控制模型的复杂度,有利于防止过拟合,从而提高模型的泛化能力。
(3)导数信息:GBDT在模型训练时只使用了代价函数的一阶导数信息,XGBoost对代价函数进行二阶泰勒展开,可以同时使用一阶和二阶导数。
(4)基分类器:传统的GBDT采用CART作为基分类器,XGBoost支持多种类型的基分类器,比如线性分类器。
(5)子采样:传统的GBDT在每轮迭代时使用全部的数据,XGBoost则采用了与随机森林相似的策略,支持对数据进行采样。
(6)缺失值处理:传统GBDT没有设计对缺失值进行处理,XGBoost能够自动学习出缺失值的处理策略。
(7)并行化:传统GBDT没有进行并行化设计,注意不是tree维度的并行,而是特征维度的并行。XGBoost预先将每个特征按特征值排好序,存储为块结构,分裂结点时可以采用多线程并行查找每个特征的最佳分割点,极大提升训练速度。
为什么XGBoost泰勒二阶展开后效果就比较好呢?
- 从为什么会想到引入泰勒二阶的角度来说(可扩展性):XGBoost官网上有说,当目标函数是MSE时,展开是一阶项(残差)+二阶项的形式,而其它目标函数,如logistic loss的展开式就没有这样的形式。为了能有个统一的形式,所以采用泰勒展开来得到二阶项,这样就能把MSE推导的那套直接复用到其它自定义损失函数上。简短来说,就是为了统一损失函数求导的形式以支持自定义损失函数。至于为什么要在形式上与MSE统一?是因为MSE是最普遍且常用的损失函数,而且求导最容易,求导后的形式也十分简单。所以理论上只要损失函数形式与MSE统一了,那就只用推导MSE就好了。
- 从二阶导本身的性质,也就是从为什么要用泰勒二阶展开的角度来说(精准性):二阶信息本身就能让梯度收敛更快更准确。这一点在优化算法里的牛顿法中已经证实。可以简单认为一阶导指引梯度方向,二阶导指引梯度方向如何变化。简单来说,相对于GBDT的一阶泰勒展开,XGBoost采用二阶泰勒展开,可以更为精准的逼近真实的损失函数。
详细可以看 为什么xgboost泰勒二阶展开后效果就比较好了呢? - 知乎
更多请关注公众号"百面机器学习",有劳东动下手指啦
XGBoost对缺失值是怎么处理的?
在普通的GBDT策略中,对于缺失值的方法是先手动对缺失值进行填充,然后当做有值的特征进行处理,但是这样人工填充不一定准确,而且没有什么理论依据。
- 在特征k上寻找最佳 split point 时,不会对该列特征 missing 的样本进行遍历,而只对该列特征值为 non-missing 的样本上对应的特征值进行遍历,通过这个技巧来减少了为稀疏离散特征寻找 split point 的时间开销。
- 在逻辑实现上,为了保证完备性,会将该特征值missing的样本分别分配到左叶子结点和右叶子结点,两种情形都计算一遍后,选择分裂后增益最大的那个方向(左分支或是右分支),作为预测时特征值缺失样本的默认分支方向。
- 如果在训练中没有缺失值而在预测中出现缺失,那么会自动将缺失值的划分方向放到右子结点。
XGBoost为什么快
- 分块并行:训练前每个特征按特征值进行排序并存储为Block结构,后面查找特征分割点时重复使用,并且支持并行查找每个特征的分割点
- 候选分位点:每个特征采用常数个分位点作为候选分割点
- CPU cache 命中优化: 使用缓存预取的方法,对每个线程分配一个连续的buffer,读取每个block中样本的梯度信息并存入连续的Buffer中。
- Block 处理优化:Block预先放入内存;Block按列进行解压缩;将Block划分到不同硬盘来提高吞吐
更多请关注公众号"百面机器学习",有劳东动下手指啦
XGBoost防止过拟合的方法
XGBoost在设计时,为了防止过拟合做了很多优化,具体如下:
- 目标函数添加正则项:叶子节点个数+叶子节点权重的L2正则化
- 列抽样:训练的时候只用一部分特征(不考虑剩余的block块即可)
- 子采样:每轮计算可以不使用全部样本,使算法更加保守
- shrinkage: 可以叫学习率或步长,为了给后面的训练留出更多的学习空间
XGBoost为什么若模型决策树的叶子节点值越大,越容易过拟合呢?
xgb最终的决策就是wx,如果某个w太大,则显然w对应叶子结点对最终的输出起到绝大部分的贡献,那么如果第一个叶子结点对应的基树拟合的过头,很容易导致整体的输出方差增大引发过拟合。更小的w表示更小的模型复杂度,因此来说w小点是好的。
详细见
XGBoost为什么若模型决策树的叶子节点值越大,越容易过拟合呢? - 知乎 https://blog.csdn.net/weixin_37933986/article/details/69681671
更多请关注公众号"百面机器学习",有劳东动下手指啦
XGBoost为什么可以并行训练?
- XGBoost的并行,并不是说每棵树可以并行训练,XGBoost本质上仍然采用boosting思想,每棵树训练前需要等前面的树训练完成才能开始训练。
- XGBoost的并行,指的是特征维度的并行:在训练之前,每个特征按特征值对样本进行预排序,并存储为Block结构,在后面查找特征分割点时可以重复使用,而且特征已经被存储为一个个block结构,那么在寻找每个特征的最佳分割点时,可以利用多线程对每个block并行计算。
XGBoost中叶子结点的权重如何计算出来
利用一元二次函数求最值的知识,当目标函数达到最小值Obj时,每个叶子结点的权重为wj。
XGBoost中的一棵树的停止生长条件
- 当新引入的一次分裂所带来的增益Gain<0时,放弃当前的分裂。这是训练损失和模型结构复杂度的博弈过程。
- 当树达到最大深度时,停止建树,因为树的深度太深容易出现过拟合,这里需要设置一个超参数max_depth。
- 当引入一次分裂后,重新计算新生成的左、右两个叶子结点的样本权重和。如果任一个叶子结点的样本权重低于某一个阈值,也会放弃此次分裂。这涉及到一个超参数:最小样本权重和,是指如果一个叶子节点包含的样本数量太少也会放弃分裂,防止树分的太细。
Xboost中的min_child_weight是什么意思
一般来说,我们定义的不带正则项的损失函数是这个
那么hi=1,Hj即叶子节点上的样本数,min_child_weight就是叶子上的最小样本数,不最小样本总数啊,只是在这个情况下是。
更多请关注公众号"百面机器学习",有劳东动下手指啦
Xgboost中的gamma是什么意思
指的是叶节点需要分裂需要的最小损失减少量,也就是
公式中的r。
详细见
xgboost中的min_child_weight是什么意思? - 知乎
更多请关注公众号"百面机器学习",有劳东动下手指啦
Xgboost中的参数
具体见 https://blog.csdn.net/han_xiaoyang/article/details/52665396
RF和GBDT的区别
相同点:
- 都是由多棵树组成,最终的结果都是由多棵树一起决定。
不同点:
- 集成学习:RF属于bagging思想,而GBDT是boosting思想
- 偏差-方差权衡:RF不断的降低模型的方差,而GBDT不断的降低模型的偏差 训练样本:RF每次迭代的样本是从全部训练集中有放回抽样形成的,而GBDT每次使用全部样本
- 并行性:RF的树可以并行生成,而GBDT只能顺序生成(需要等上一棵树完全生成)
- 最终结果:RF最终是多棵树进行多数表决(回归问题是取平均),而GBDT是加权融合
- 数据敏感性:RF对异常值不敏感,而GBDT对异常值比较敏感
- 泛化能力:RF不易过拟合,而GBDT容易过拟合
xgboost本质上是树模型,能进行线性回归拟合么
Xgboost中可以使用的,gbliner这个参数,那么它就使用线性基学习器来进行学习了。
Xgboos是如何调参的
一般来说主要调节的几个参数有如下
- max_depth
- learning_rate
- n_estimators
- min_child_weight
- subsample
- colsample_bytree
XGBoost的作者把所有的参数分成了三类:
1、通用参数:宏观函数控制。
2、Booster参数:控制每一步的booster(tree/regression)。
3、学习目标参数:控制训练目标的表现。
调参主要由一下步骤
- 确定数据的的情况,设置好相应的参数
- 调参方法1:
- 选择较高的学习速率(learning rate)。一般情况下,学习速率的值为0.1。但是,对于不同的问题,理想的学习速率有时候会在0.05到0.3之间波动。选择对应于此学习速率的理想决策树数量。XGBoost有一个很有用的函数“cv”,这个函数可以在每一次迭代中使用交叉验证,并返回理想的决策树数量。
- 对于给定的学习速率和决策树数量,进行决策树特定参数调优(max_depth, min_child_weight, gamma, subsample, colsample_bytree)。在确定一棵树的过程中,我们可以选择不同的参数,待会儿我会举例说明。
- xgboost的正则化参数的调优。(lambda, alpha)。这些参数可以降低模型的复杂度,从而提高模型的表现。4. 降低学习速率,确定理想参数。
- 调参方法2:
使用网格搜索 - 调参方法3:
使用随机搜索 - 调参方法4:
使用贝叶斯调参方法 详细见
【转】XGBoost参数调优完全指南(附Python代码) - 知乎
为什么xgboost/gbdt在调参时为什么树的深度很少就能达到很高的精度?
Boosting主要关注降低偏差,因此Boosting能基于泛化性能相当弱的学习器构建出很强的集成;Bagging主要关注降低方差,因此它在不剪枝的决策树、神经网络等学习器上效用更为明显。
gbdt属于boosting的方法,其主要关注的是减少偏差,多棵树进行叠加后可以保证较高的精度。
更多请关注公众号"百面机器学习",有劳东动下手指啦
为什么常规的gbdt和xgboost不适用于类别特别多的特征?
one-hot coding是类别特征的一种通用解决方法,然而在树模型里面,这并不是一个比较好的方案,尤其当类别特征维度很高的时候。主要的问题是:
- 可能无法在这个类别特征上进行切分
使用one-hot coding的话,意味着在每一个决策节点上只能用 one-vs-rest (例如是不是狗,是不是猫,等等) 的切分方式。当特征纬度高时,每个类别上的数据都会比较少,这时候产生的切分不平衡,切分增益(split gain)也会很小(比较直观的理解是,不平衡的切分和不切分几乎没有区别)。 - 会影响决策树的学习
因为就算可以在这个类别特征进行切分,也会把数据切分到很多零散的小空间上,如图1左所示。而决策树学习时利用的是统计信息,在这些数据量小的空间上,统计信息不准确,学习会变差。但如果使用图1右边的切分方法,数据会被切分到两个比较大的空间,进一步的学习也会更好。
怎么处理类别特征在树模型下?
- 可以使用lightGBM模型
- 可以用embedding
- 其他的编码方法,比如binary coding
详细见
https://www.zhihu.com/question/2661
以上是关于机器学习面试题总结的主要内容,如果未能解决你的问题,请参考以下文章