提示:东西多而杂乱,但是也要过一遍,因为大厂笔试经常考,难保面试也考……
机器学习面试题汇总与解析——集成学习、Adaboost、随机森林、GBDT、xgBoost、LightGBM
什么是GBDT
什么是xgBoost
什么是lightGBM
LightGBM和xgBoost、GBDT的区别
xgBoost和gbdt的区别
xgBoost的block结构
XGBoost的优缺点
集成学习 Bagging Boosting
RF和GBDT的区别
GBDT是否适合于处理大规模的ID特征
LightGBM的直方图 排序后会比xgboost的效果差吗,为什么
xgboost正则化项和什么有关
随机森林哪两个随机
bootstrap怎么做的
介绍GBDT的详细计算过程
xgb的正则项是什么
xgboost缺失值处理方法
为什么xgboost要二阶展开?
集成学习的方法有哪些
泰勒公式求e的近似值
XGBoost 如果损失函数没有二阶导,该怎么办
GBDT的G梯度的向量长度为多少
GBDT(Gradient Boosting Decision Tree),全名叫梯度提升决策树,使用的是Boosting的思想。
Boosting方法训练基分类器时采用串行的方式,各个基分类器之间有依赖。
它的基本思路是将基分类器层层叠加,每一层在训练的时候,对前一层基分类器分错的样本,给予更高的权重。
测试时,根据各层分类器的结果的加权得到最终结果。
Bagging与Boosting的串行训练方式不同,Bagging方法在训练过程中,各基分类器之间无强依赖,可以进行并行训练。
GBDT的原理很简单,就是所有弱分类器的结果相加等于预测值,
然后下一个弱分类器去拟合误差函数对预测值的残差
(这个残差就是预测值与真实值之间的误差)。
当然了,它里面的弱分类器的表现形式就是各棵树。
举一个非常简单的例子,比如我今年30岁,但计算机或者模型GBDT并不知道我今年多少岁,那GBDT咋办呢?
它会在第一个弱分类器(或第一棵树中)随便用一个年龄比如20岁来拟合,然后发现误差有10岁;
接下来在第二棵树中,用6岁去拟合剩下的损失,发现差距还有4岁;
接着在第三棵树中用3岁拟合剩下的差距,发现差距只有1岁了;
最后在第四课树中用1岁拟合剩下的残差,完美。
最终,四棵树的结论加起来,就是真实年龄30岁
(实际工程中,gbdt是计算负梯度,用负梯度近似残差)。
为何gbdt可以用用负梯度近似残差呢?
回归任务下,GBDT 在每一轮的迭代时对每个样本都会有一个预测值,此时的损失函数为均方差损失函数:
负梯度是这样计算的:
当损失函数选用均方损失函数是时,每一次拟合的值就是(真实值 - 当前模型预测的值),即残差。
两者都是在每 一轮迭代中,利用损失函数相对于模型的负梯度方向的信息来对当前模型进行更 新
只不过在梯度下降中,模型是以参数化形式表示,从而模型的更新等价于参 数的更新。
而在梯度提升中,模型并不需要进行参数化表示,而是直接定义在函 数空间中,从而大大扩展了可以使用的模型种类。
(1)预测阶段的计算速度快,树与树之间可并行化计算。
(2)在分布稠密的数据集上,泛化能力和表达能力都很好,这使得GBDT在Kaggle的众多竞赛中,经常名列榜首。
(3)采用决策树作为弱分类器使得GBDT模型具有较好的解释性和鲁棒性,能够自动发现特征间的高阶关系。
(1)GBDT在**高维稀疏 的数据集上,表现不如支持向量机或者神经网络。
(2)GBDT在处理文本分类 **特征问题上,相对其他模型的优势不如它在处理数值特征时明显。
(3)训练过程需要串行训练,只能在决策树内部采用一些局部并行的手段提高训练速度。
XGBoost是陈天奇等人开发的一个开源机器学习项目,高效地实现了GBDT算法并进行了算法和工程上的许多改进,被广泛应用在Kaggle竞赛及其他许多机器学习竞赛中并取得了不错的成绩。
因为XGBoost本质上还是一个GBDT,但是力争把速度和效率发挥到极致,所以叫X (Extreme) GBoosted。
先来举个例子,我们要预测一家人对电子游戏的喜好程度,考虑到年轻和年老相比,年轻更可能喜欢电子游戏,以及男性和女性相比,男性更喜欢电子游戏,故先根据年龄大小区分小孩和大人,然后再通过性别区分开是男是女,逐一给各人在电子游戏喜好程度上打分,如下图所示。
就这样,训练出了2棵树tree1和tree2,类似之前gbdt的原理,两棵树的结论累加起来便是最终的结论,所以小孩的预测分数就是两棵树中小孩所落到的结点的分数相加:2 + 0.9 = 2.9。爷爷的预测分数同理:-1 + (-0.9)= -1.9。具体如下图所示:
XGBoost与GBDT比较大的不同就是目标函数的定义。XGBoost的目标函数如下图所示:
其中:
红色箭头所指向的L 即为损失函数(比如平方损失函数:l(yi,yi)=(yi−yi)2)
红色方框所框起来的是正则项(包括L1正则、L2正则)
红色圆圈所圈起来的为常数项
对于f(x),XGBoost利用泰勒展开三项,做一个近似。f(x)表示的是其中一颗回归树。
(1)不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数f(x),去拟合上次预测的残差。
(2)当我们训练完成得到k棵树,我们要预测一个样本的分数,其实就是根据这个样本的特征,在每棵树中会落到对应的一个叶子节点,每个叶子节点就对应一个分数
(3)最后只需要将每棵树对应的分数累加起来就是该样本的预测值。
LightGBM(Light Gradient Boosting Machine)是一个实现GBDT算法的框架,支持高效率的并行训练,并且具有更快的训练速度、更低的内存消耗、更好的准确率、支持分布式可以快速处理海量数据等优点。
(1)基于Histogram的决策树算法。
(2)单边梯度采样 Gradient-based One-Side Sampling(GOSS):使用GOSS可以减少大量只具有小梯度的数据实例,这样在计算信息增益的时候只利用剩下的具有高梯度的数据就可以了,相比XGBoost遍历所有特征值节省了不少时间和空间上的开销。
(3)互斥特征捆绑 Exclusive Feature Bundling(EFB):使用EFB可以将许多互斥的特征绑定为一个特征,这样达到了降维的目的。
(4)带深度限制的Leaf-wise的叶子生长策略:大多数GBDT工具使用低效的按层生长 (level-wise) 的决策树生长策略,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销。实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。LightGBM使用了带有深度限制的按叶子生长 (leaf-wise) 算法。
(5)直接支持类别特征(Categorical Feature)
(6)支持高效并行
(7)Cache命中率优化
(1)切分算法(切分点的选取):XGBoost通过对所有特征都按照特征的数值进行预排序选取最好的分割点;LightGBM通过直方图算法寻找最优的分割点
(2)LightGBM占用的内存更低,只保存特征离散化后的值,而这个值一般用8位整型存储就足够了,内存消耗可以降低为原来的1/8
(3)LightGBM直接支持类别特征
(4)决策树生长策略不同
——XGBoost采用的是带深度限制的level-wise生长策略。level-wise过一次数据可以能够同时分裂同一层的叶子,容易进行多线程优化,不容易过拟合;但不加区分的对待同一层叶子,带来了很多没必要的开销(实际上很多叶子的分裂增益较低,没必要进行搜索和分裂)
——LightGBM采用leaf-wise生长策略,每次从当前所有叶子中找到分裂增益最大(数据量最大)的一个叶子,进行分裂,如此循环;但会生长出比较深的决策树,产生过拟合(因此LightGBM在leaf-wise之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合)
(1)传统GBDT以CART作为基分类器,xgboost还支持线性分类器,这个时候xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。
(3)传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数,训练速度更快。
(4)xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。防止过拟合
(5)Shrinkage(缩减),相当于学习速率(xgboost中的eta)。xgboost在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。
(6)列抽样(column subsampling)。xgboost借鉴了随机森林的做法,支持列抽样,不仅能降低过拟合,还能减少计算,这也是xgboost异于传统gbdt的一个特性。对缺失值的处理。对于特征的值有缺失的样本,xgboost可以自动学习出它的分裂方向;传统的GBDT没有设计对缺失值进行处理
(7)xgboost工具支持并行。GBDT属于串行。
(8)GBDT是机器学习算法,XGBoost是该算法的工程实现。
答:如果LightGBM的直方图排序后,最优的分割点就变了,效果可能会比xgboost差。
(1)基于树模型的boosting算法,很多算法比如xgboost都是用预排序(pre-sorting)算法进行特征的选择和分裂
(2)LightGBM采用HistoGram算法,其思想是将连续的浮点特征离散成k个离散值,并构造宽度为k的Histogram。然后遍历训练数据,计算每个离散值在直方图中的累计统计量。在进行特征选择时,只需要根据直方图的离散值,遍历寻找最优的分割点。
xgBoost、GBDT的区别
(1)传统GBDT以CART作为基分类器,xgboost还支持线性分类器,这个时候xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。
(2)传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数,训练速度更快。
(3)xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。防止过拟合
(4)Shrinkage(缩减),相当于学习速率(xgboost中的eta)。xgboost在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。
(5)列抽样(column subsampling)。xgboost借鉴了随机森林RT的做法,支持列抽样,不仅能降低过拟合,还能减少计算,这也是xgboost异于传统gbdt的一个特性。
(6)对缺失值的处理。对于特征的值有缺失的样本,xgboost可以自动学习出它的分裂方向;传统的GBDT没有设计对缺失值进行处理
(7)xgboost工具支持并行。GBDT属于串行。
(8)GBDT是机器学习算法,XGBoost是该算法的工程实现。
在树生成过程中,最耗时的一个步骤就是在每次寻找最佳分裂点时都需要对特征的值进行排序。而 XGBoost 在训练之前会根据特征对数据进行排序,然后保存到块结构中,并在每个块结构中都采用了稀疏矩阵存储格式(Compressed Sparse Columns Format,CSC)进行存储,后面的训练过程中会重复地使用块结构,可以大大减小计算量。
作者提出通过按特征进行分块并排序,在块里面保存排序后的特征值及对应样本的引用,以便于获取样本的一阶、二阶导数值。具体方式如图:
通过顺序访问排序后的块遍历样本特征的特征值,方便进行切分点的查找。此外分块存储后多个特征之间互不干涉,可以使用多线程同时对不同的特征进行切分点查找,即特征的并行化处理。在对节点进行分裂时需要选择增益最大的特征作为分裂,这时各个特征的增益计算可以同时进行,这也是 XGBoost 能够实现分布式或者多线程计算的原因。
(1)精度更高:GBDT 只用到一阶泰勒展开,而 XGBoost 对损失函数进行了二阶泰勒展开。XGBoost 引入二阶导一方面是为了增加精度,另一方面也是为了能够自定义损失函数,二阶泰勒展开可以近似大量损失函数;
(2)灵活性更强:GBDT 以 CART 作为基分类器,XGBoost 不仅支持 CART 还支持线性分类器,使用线性分类器的 XGBoost 相当于带 L1 和 L2 正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。此外,XGBoost 工具支持自定义损失函数,只需函数支持一阶和二阶求导;
(3)**正则化:**XGBoost 在目标函数中加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、叶子节点权重的 L2 范式。正则项降低了模型的方差,使学习出来的模型更加简单,有助于防止过拟合,这也是XGBoost优于传统GBDT的一个特性。
(4)**Shrinkage(缩减):相当于学习速率。**XGBoost 在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。传统GBDT的实现也有学习速率;
(5)**列抽样:XGBoost 借鉴了随机森林的做法,支持列抽样,不仅能降低过拟合,还能减少计算。**这也是XGBoost异于传统GBDT的一个特性;
(6)缺失值处理:对于特征的值有缺失的样本,XGBoost 采用的稀疏感知算法可以自动学习出它的分裂方向;
(7)**XGBoost工具支持并行:**XGBoost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。
(8)可并行的近似算法:树节点在进行分裂时,我们需要计算每个特征的每个分割点对应的增益,即用贪心法枚举所有可能的分割点。当数据无法一次载入内存或者在分布式情况下,贪心算法效率就会变得很低,所以XGBoost还提出了一种可并行的近似算法,用于高效地生成候选的分割点。
(1)虽然利用预排序和近似算法可以降低寻找最佳分裂点的计算量,但在节点分裂过程中仍需要遍历数据集;
(2)预排序过程的空间复杂度过高,不仅需要存储特征值,还需要存储特征对应样本的梯度统计值的索引,相当于消耗了两倍的内存。
【正常,空间换时间,速度快的必然额外复杂度高】
集成学习方法大致可以分为两类:
(1)个体学习器间存在强依赖关系、必须串行生成的序列化方法,代表为Boosting;
(2)个体学习器间不存在强依赖关系、可同时生成的并行化方法,代表为Bagging和随机森林。
注:所谓串行生成的序列化方法就是除了训练第一个之外,其他的学习器学习都需要依赖于前面生成的学习的结果。
——Bagging 是 bootstrap aggregation的缩写。
bagging对于数据集进行bootstrap取样,每个数据点有同等几率被采样,然后创建n个模型,每个模型进行m个数据采样,最后进行投票(voting)得出最后结果。Bagging 的典型应用是随机森林
基于每个采样集训练出T个基学习器,再将这些基学习器进行结合,即可得到集成学习器。然后基于每个采样集训练出T个基学习器,再将这些基学习器进行结合,即可得到集成学习器。在对输出进行预测时,Bagging通常对分类进行简单投票法,对回归使用简单平均法。
随机森林RF在以决策树为基学习器构建Bagging集成的基础上,进一步在决策树的训练过程中引入了随机属性选择。
—— boosting创建了一系列预测器,或者说是学习器。前面的学习器用简单的模型去适配数据,然后分析错误。然后会给予错误预测的数据更高权重,然后用后面的学习器去修复。boosting通过把一些弱学习器串起来,组成一个强学习器。boosting的典型应用是Adaboost、提升树(Boosting Tree)、GBDT。
(1)都是由多棵树组成,最终的结果都是由多棵树一起决定。
(2)RF和GBDT在使用CART树时,可以是分类树或者回归树。
(1)组成随机森林的树可以并行生成,而GBDT是串行生成
(2)随机森林的结果是多数表决表决的,而GBDT则是多棵树累加之和
(3)随机森林对**异常值不敏感 ,而GBDT对异常值比较敏感**
(4)随机森林是减少模型的方差,而GBDT是减少模型的偏差
(5)随机森林**不需要 进行特征归一化。而GBDT则需要进行特征归一化**
答:不适合
GBDT对于海量的id类特征,GBDT由于树的深度和树的数量限制(防止过拟合),不能有效存储;
另外海量特征也会存在性能瓶颈,当GBDT的one hot特征大于100k维时,需要做分布式训练才能保证不爆内存,因此,GBDT通常配合少量的反馈CTR特征来表达,在带来一定范化能力的同时会有信息损失,对于头部资源无法有效表达。
则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。
2个随机(bootstrap+特征m)
(1)应用 bootstrap 法有放回地随机抽取 k个新的自助样本集(boostrap),并由此构建 k 棵分类树(ID3 、 C4.5 、 CART)样本扰动。
(2)先随机选择属性子集,个数为k,然后再从这个子集中选择一个最优属性用于划分。
Bootstrap是一种抽样方法,即随机抽取数据并将其放回。如一次抽取一个样本,然后放回样本集中,下次可能再抽取这个样本。
论文中关于缺失值的处理将其看与稀疏矩阵的处理看作一样。在寻找split point的时候,不会对该特征为missing的样本进行遍历统计,只对该列特征值为non-missing的样本上对应的特征值进行遍历,通过这个技巧来减少了为稀疏离散特征寻找split point的时间开销。
在逻辑实现上,为了保证完备性,会分别处理将missing该特征值的样本分配到左叶子结点和右叶子结点的两种情形,计算增益后选择增益大的方向进行分裂即可。可以为缺失值或者指定的值指定分支的默认方向,这能大大提升算法的效率。
如果在训练中没有缺失值而在预测中出现缺失,那么会自动将缺失值的划分方向放到右子树。
(1)xgboost是以mse为基础推导出来的,在mse的情况下,xgboost的目标函数展开就是一阶项+二阶项的形式,而其他类似log loss这样的目标函数不能表示成这种形式。
为了后续推导的统一,所以将目标函数进行二阶泰勒展开,就可以直接自定义损失函数了,只要二阶可导即可,增强了模型的扩展性。
(2)二阶信息能够让梯度收敛的更快,类似牛顿法比SGD收敛更快。一阶信息描述梯度变化方向,二阶信息可以描述梯度变化方向是如何变化的。
自然常数 e 可以用级数 1+1/1!+1/2!+⋯+1/n!+⋯ 来近似计算。
gbdt的目标函数与xgboost区别就是带不带正则项(算法内容上)。
gbdt对损失函数的优化是直接使用了损失函数的负梯度,沿着梯度下降的方向来减小损失,其是也就是一阶泰勒展开。
而xgboost在这里使用了二阶泰勒展开,因为包含了损失函数的二阶信息,其优化的速度大大加快。
但如果loss没有二阶导数,就使用一阶导数优化
样本数
提示:重要经验:
1)这篇文章设计的东西很多,主要是集成学习包括并行和串行
2)并行的集成学习:bagging,随机森林RT
3)串行的集成学习:boosting,GBDT是核心算法,XGBDT,lightGBM是工程实现,他们都是一家的