机器学习之面试题

翻看csdn里的博客,无意间看到一篇分享机器学习面试经验的文章,里面博主列举了他面试遇到的问题,我觉得很不错,然后加上我个人的理解分享给需要的人。

1、 什么是boosting tree?

提升方法(boosting)是一种常见的统计学习方法,它的理论基础是:强可学习与弱可学习是等价的,在概率近似正确(PAC)学习的框架下:

  • 强可学习是一个概念,若存在一个多项式的学习算法能够学习它,并且正确率很高,那么称这个概念为强可学习的;
  • 弱可学习是一个概念,若存在一个多项式学习算法能够学习它,学习的正确率仅比随机猜测略好,那么称这个概念为若可学习的。
    对于分类分问题,构建弱分类器比强分类器简单许多,提升方法就是一族可以将弱学习器提升为强学习器的算法。

训练过程如下:

  1. 先从初始数据集训练出一个基学习器;
  2. 再根据基学习器的表现对训练样本权重进行调整,使得被先前的基学习器误判断的样本在后续得到更多关注;
  3. 然后基于调整后的样本权重来训练下一个学习器;
  4. 如此重复,知道基学习器大到给定的值M为止;
  5. 最后将这M个基学习器进行加权组合得到集成学习器。

提升树是以决策树为基学习器的提升方法。可以表示成以决策树为基学习器的加法模型:

f M ( x ) = m = 1 M T ( x ; Θ m )
T 表示决策树, Θ 是决策树的参数,M是树的个数。
提升树采用向前分步算法,首先确定初始提升树 f 0 ( x ) = 0 , 第m步的模型:
f m ( x ) = f m 1 ( x ) + T ( x ; Θ m )

f m 1 ( x ) 是当前模型,通过经验风险极小化确定下一棵树的参数:
Θ ^ m = a r g max Θ m i = 1 N L ( y i , f m 1 ( x i ) + T ( x i ; Θ m ) )

由于树的线性组合可以很好的拟合训练数据,即使数据中的输入与输出之间关系很复杂,所以提升树是一种高效的学习算法。对于回归问题,通常采用的损失函数是平凡误差: L ( y , y ^ ) = ( y y ^ ) 2 ; 对于分类问题,则采用指数损失函数: L ( y , y ^ ) = e y y ^

2、 解释一下GBDT?

提升树利用加法模型与前向分步算法实现学习的优化过程中,当损失函数是平方损失或指数损失时,优化求解比较容易。但是对于一般损失函数,优化过程往往不太容易。于是大牛Freidman提出了一种通用的做法:梯度提升算法(gradient boosting)这是利用梯度下降的近似方法,利用损失函数的负梯度在当前模型的值作为算法中残差的近似值,拟合一棵决策树。在回归问题中,称为梯度提升回归树GBRT,在分类问题中,称为梯度提升决策树GBDT。
那么问题来了,为什么我们可以利用损失函数的负梯度来当作残差的近似呢?
其实残差是平方损失函数下的特例。对于其他损失函数,其负梯度就不是残差了。至于说负梯度是残差的近似值,数学上可以这么理解:对于模型的损失函数

L ( y , y ^ ) = L ( y , f m 1 + T ( x ; Θ m ) )
将其在 L ( y , f m 1 ) 邻域做二阶泰勒级数展开, 有
L ( y , f m 1 + T ( x ; Θ m ) ) = L ( y , f m 1 ) + g T ( x ; Θ m ) + 1 2 h T ( x ; Θ m ) 2

其中g和h是一阶和二阶偏导
g = δ L ( y , f m 1 ) δ f m 1 , h = δ 2 L ( y , f m 1 ) δ f m 1

为求极值,对上式求偏导,并让其等于0,得到 T ( x ; Θ m ) = g h 。对于平方损失函数 g = f m 1 y , 残差等于负梯度, h=1, 且没有更高阶导数,结果就是用负梯度拟合新的树函数。对于其他损失函数,仍旧设h=1, 舍弃高阶项, 相当于拟合残差的近似值。如果加上正则化项, T(x;\Theta_m)变为 g h + λ , 就是xgboost的实现了。
为什么要沿着Loss的负梯度去做Boosting这个在宏观上也很好解释,因为Loss的负梯度是下降的方向。在传统的LR等Model中,训练的时候是用梯度下降来尽可能逼近Loss的近似最优值,所以在Boosting里面,也是通过沿着负梯度不断拟合这个值来使得整体的偏差尽可能的沿着Loss最小的方向走,这个直观上应该很好理解。

3、L1和L2正则为何可以减弱over-fitting?

首先我们知道,监督机器学习问题无非就是最小化损失函数使得我们的模型拟合训练数据,但是过于复杂的模型会导致过拟合,即训练误差很小,但是预测误差很大。我们需要保证模型“简单”的基础上最小化训练误差,而通过加入L1和L2正则项,我们可以人为降低模型复杂度,强行让学习到的模型具有我们想要的特性,如稀疏、低秩、平滑等。正则化是符合奥卡姆剃刀原理的,也是说在可能选择的模型中,我们应该选择能够很好的解释已知数据并且十分简单的模型。从贝叶斯估计得角度来看,正则项对应于模型的先验概率。还有个说法,正则化是结构风险最小化策略的实现,是在经验风险上加入了惩罚项。

4、L1和L2正则有什么区别?

L1和L2正则分别对应于在损失函数上加入L1和L2范数。L1范数是向量中各个元素绝对值之和,它可以实现权重稀疏,也就是使得一部分权重变为0,达到特征选择的作用,使得模型容易解释。L2范数是向量各元素的平方和之后求平方根。它可以使得权重衰减,接近于0。区别有:首先下降速度,L1是绝对值一阶函数, L2是平方二阶函数,由图像我们可以知道在0附近L1比L2下降更快。其次,他们对模型空间的限制不同。考虑二位空间下,L1会与坐标轴相交处会有角出现,实现稀疏,也就是趋向于产生少量特征,而其他特征的权重为0。而L2会选择更多的特征,其都会接近于0。L1常用于特征选择,L2只是一种正则化。

5、KNN和LR有什么本质区别?

KNN与LR的本质区别有:

  1. knn是惰性学习算法,不会去自主学习特征权重。它没有训练过程,基本原理就是找到训练数据集里面离需要预测的样本点距离最近的k个值(距离可以使用比如欧式距离,k的值需要自己调参),然后把这k个点的label做个投票,选出一个label做为预测。这是与LR最本质的区别。
  2. knn是基于距离的,LR基于概率。所以knn需要事先对数据进行归一化,而LR对数据没有太多约束。
  3. LR适用与高维稀疏数据,而knn对于大型数据的预测结果很糟糕。

下面,我们看看LR与SVM的相同与不同处。

相同处:

  • 都是线性分类算法;
  • 都属于判别模型;
  • 都是监督学习算法;
  • 都适用于高维数据,在工业界都得到了广泛使用。

不同处:

  • 本质上,损失函数不同。LR是log损失函数,SVM是Hinge损失函数,这是0-1损失函数的一种变体。不同的loss function代表了不同的假设前提,也就代表了不同的分类原理。简单来说,​逻辑回归方法基于概率理论,假设样本为1的概率可以用sigmoid函数来表示,然后通过极大似然估计的方法估计出参数的值。支持向量机​基于几何间隔最大化原理,认为存在最大几何间隔的分类面为最优分类面。
  • 支持向量机只考虑局部的边界线附近的点,而逻辑回归考虑全局。SVM决策面的样本点只有少数的结构支持向量,当在支持向量外添加或减少任何样本点对分类决策面没有任何影响;而在LR中,每个样本点都会或多或少影响决策面的结果。因此,线性SVM不直接依赖于数据分布,分类平面不受一类点影响;LR则受所有数据点的影响,如果数据不同类别strongly unbalance,一般需要先对数据做balancing。
  • 在解决非线性问题时,支持向量机采用核函数的机制,而LR通常不采用核函数的方法。分类模型的结果就是计算决策面,模型训练的过程就是决策面的计算过程。通过上面的第二点不同点可以了解,在计算决策面时,SVM算法里只有少数几个代表支持向量的样本参与了计算,也就是只有少数几个样本需要参与核计算(即kernal machine解的系数是稀疏的)。然而,LR算法里,每个样本点都必须参与决策面的计算过程,也就是说,假设我们在LR里也运用核函数的原理,那么每个样本点都必须参与核计算,这带来的计算复杂度是相当高的。所以,在具体应用时,LR很少运用核函数机制。​
  • ​线性SVM依赖数据表达的距离测度,所以需要对数据先做normalization,LR不受其影响。一个基于概率,一个基于距离!同时会有:feature scaling会使得gradient descent的收敛更好。
  • SVM的损失函数就自带正则,损失函数中的 1 / 2 | | w | | 2 项,这就是为什么SVM是结构风险最小化算法的原因. 而LR必须另外在损失函数上添加正则项!因此,两个模型对参数的敏感程度不同,Linear SVM比较依赖penalty的系数和数据表达空间的测度,而(带正则项的)LR比较依赖对参数做L1 regularization的系数。

6、怎么理解Dropout?

Dropout 是深度学习中的一种正则化方法,指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。注意是暂时,对于随机梯度下降来说,由于是随机丢弃,故而每一个mini-batch都在训练不同的网络。由于大规模神经网络具有两个显著缺点:计算费时和过拟合。问了解决过拟合,一般采用essenble方法,即训练多个模型进行组合,但是这对于大型神经网络是不可取的。Dropout可以被看作是集成大量深度神经网络的使用Bagging方法,比如对于具有N个结点的网络,使用dropout随机进行丢弃后,可以看成 2 n 个“瘦小“的神经网络的集合,达到了一种廉价的Bagging集成近似,但是训练的参数却是不变的。从而摆脱了费事的问题,能够方便且功能强大的训练和评估指数级数量的神经网络。一个关于dropout的重要见解是,通过随机行为训练网络并平均多个随机决定进行预测,实现了一种参数共享的Bagging形式。这种参数共享不一定基于包括和排除。原则上,任何一种随机的修改都是可以接受的。在实践中,我们必须选择让神经网络能够学习对抗的修改类型。
更进一步的观点是:dropout不仅仅是训练一个bagging的集成模型,而且是共享隐藏单元的集成模型。受生物学想法启发:有性繁殖涉及两个不同生物体之间交换基因,进化产生的压力使得基因不仅是良好的,而且要准备好不同有机体之间的交换,这样的基因和这些特点对环境的变化是非常稳健的,因为它们一定会正确适应任何一个有机体或模型不寻常的特性。因此Dropout正则化每个隐藏单元不仅是一个很好的特征,要在很多情况下是良好的特征,dropout会强迫一个神经单元,和随机挑选出来的其他神经单元共同工作,达到好的效果。消除减弱了神经元节点间的联合适应性,增强了泛化能力。
另外还有一种观点是:Dropout是施加到隐藏单元的掩码噪音。就是对于每一个dropout后的网络,进行训练时,相当于做了Data Augmentation,因为,总可以找到一个样本,使得在原始的网络上也能达到dropout单元后的效果。 比如,对于某一层,dropout一些单元后,形成的结果是(1.5,0,2.5,0,1,2,0),其中0是被drop的单元,那么总能找到一个样本,使得结果也是如此。这样,每一次dropout其实都相当于增加了样本。

7、为什么random forest具有特征选择的功能?

首先我们知道,决策树是一种易解释的模型,它可以对特征的重要性进行排序,而随机森林是由决策树构建而成的,一定程度上了揭示了它也是是由特征选择的功能的。那么随机森林如何对特征进行选取呢?方法如下:

  • 平均不纯度减少 mean decrease impurity:随机森林由多个决策树构成。决策树中的每一个节点都是关于某个特征的条件,为的是将数据集按照不同的响应变量一分为二。利用不纯度可以确定节点(最优条件),对于分类问题,通常采用基尼不纯度或者信息增益,对于回归问题,通常采用的是方差或者最小二乘拟合。当训练决策树的时候,可以计算出每个特征减少了多少树的不纯度。对于一个决策树森林来说,可以算出每个特征平均减少了多少不纯度,并把它平均减少的不纯度作为特征选择的值。

  • 平均精确率减少 Mean decrease accuracy:度量每个特征对模型精确率的影响。主要思路是打乱每个特征的特征值顺序,并且度量顺序变动对模型的精确率的影响。很明显,对于不重要的变量来说,打乱顺序对模型的精确率影响不会太大,但是对于重要的变量来说,打乱顺序就会降低模型的精确率。

8、random forest有哪些重要的参数?

重要的参数有:构建随机森林的决策树的数量;每棵树的最大深度;每棵树包含的最大特征数。随机森林通过对样本随机采样,随机选取特征来构建决策树,通过k棵决策树组合成最终的分类器。

9、 DNN为什么功能强大,说说你的理解?

DNN,深度神经网络。机器学习的大部分任务任务简单来说就是从训练数据中学习到一个映射函数,然后用于未知数据的预测。而DNN理论上可以拟合任意的线性非线性函数。传统的机器学习算法可能对线性模型拟合效果很好,对非线性的效果一般较差。DNN通过加入多层的隐藏层以及激活函数,大大的加强了模型对非线性关系的拟合能力。所以说,只要数据足够,计算能力足够,DNN的功能是十分强大的。

10、 SVM的损失函数是什么?怎么理解。

SVM的损失函数是Hinge损失函数,是0-1损失函数的一种变体。对于线性与非线性其表达式略有不同。考虑二分类问题,label={-1,1 }。线性可分时的损失函数形式如下:

L p = 1 2 w 2 i = 1 N λ i ( y i ( w x i + b ) 1 )

我们知道SVM的学习任务是最大化决策边界的边缘距离 2 w ,但是对参数w有一定的约束, 我们希望:
w x i + b 1 , i f   y i = 1 w x i + b 1 , i f   y i = 1

也就是说要求所有标号为1的实例样本都位于 w x + b = 1 平面上方,多有-1的实例样本都位于 w x + b = 1 的下方。综合起来写成: y i ( x x i + b ) 1 ,   i = 1 , 2 , . . . , N 。所以学习任务成了如下的约束问题:
min w w 2 2 s . t     y i ( w x i + b ) 1

这个凸优化问题,可以通过拉格朗日乘子法求解,通过引入拉格朗日乘子 λ i 得到了上面所说的损失函数 L p
对于线性不可分情况,需要引入松弛变量 ξ 来实现。 ξ 提供了决策边界在训练样本上的误差估计。对于非线性情况,则需用到核技巧。


11、 介绍下Maxout?

maxout 单元进一步扩展了整流线性单元。其将 z 划分为每组具有 k 个值的组,而不是使用作用于每个元素的函数 g ( z ) 。每个maxout单元则输出每组的最大元素:

g ( z ) i = max j G ( i ) z j

这里 G ( i ) 是组 i 的输入索引集 { ( i 1 ) k + 1 , . . . , i k } ,这提供了一种方法来学习输入 x 空间中多个反向响应的分段线性函数。

12、项目中over-fitting了,你怎么办?

机器学习的一个核心问题是:设计的模型不仅在训练数据上表现好,同时在新输入上泛化好。过拟合指的是训练误差与测试误差之间的差距太大。我们可以通过加入一些正则化来减小测试误差,防止过拟合。具体的方法有:

  1. 参数范数惩罚,如加入L1、L2参数正则化。通过惩罚模型参数来控制模型复杂度,达到防止过拟合的目的。
  2. 数据集增强,理论上可以证明训练误差和测试误差之间差异的上界随着样本数据的增多而减少。
  3. 提前终止,对于大型模型会出现随着训练误差越来越低而验证集上的误差反而再次升高的现象。提前终止是深度学习中常用的正则化策略。
  4. 集成方法,如bagging、boosting和stacking方法,通过模型平均来有效的减小泛化误差。
  5. Dropout,深度学习中的防止过拟合的策略。

13、 详细说一个你知道的优化算法(Adam等)?

详细可以看这篇博文优化算法

14、项目(比赛)怎么做的模型的ensemble?
15、stacking是什么?需要注意哪些问题?

stacking 不一种不同于bagging、boosting的组合模型算法,重点在于对不同学习器的组合。具体过程如下:

  • 划分数据集为两个不相交的集合 A 与 B
  • 在集合A上训练m个学习器
  • 在集合B上测试这m个学习器
  • 将上述预测结果作为输入,把正确的label作为输出,训练一个高层学习器

stcking属于集成学习 ensemble learning 的一种。
集成学习是将多个学习算法组合在一起来获得更好效果的一种方法。
机器学习中,监督学习可以描述成:对于一个具体问题,从一堆假设空间中搜索一个具有较好且相对稳定预测效果的模型。
即使假设空间中包含很好的假设,有时我们也难以找出。集成方法通过组合多个假设以期望得到一个更优的假设,也就是说通过组合多个弱学习器以构成一个强学习器。其中组合的弱学习模型可以是相同类型的,也可以是不同的。
集成方法对大量数据和不充分数据都有很好的效果,对于大数据,将其分成若干小数据集,分别进行训练,最后组合在一起。如果数据量少,可以通过boostrap进行抽象,得到多个数据集,分别训练后再组合。
集成方法用于评估测试的时候,需要更多的计算。可以认为集成学习使用计算换预测效果。同时这也造成了模型中的参数相比单一模型包含的信息较少,导致了太多的冗余。

16、了解哪些online learning的算法?

17、如何解决样本不均衡的问题?
18、fasterRCNN中的ROIPooling是如何实现的?
19、如何进行特征的选择?
20、如何进行模型的选择?
21、什么是梯度消失?怎么解决?

22、常用的有哪些损失函数?

除了我们常用的平方损失函数,绝对值损失函数。详见之前的文章机器学习之损失函数
任何一 个由负对数似然组成的损失都是定义在训练集上的经验分布和定义在模型上的概率 分布之间的交叉熵。例如,均方误差是经验分布和高斯模型之间的交叉熵。

23、XX用户画像挖掘怎么做的feature engineering?
24、假设一个5*5的filter与图像卷积,如何降低计算量?
25、做过模型压缩吗?介绍下

众所周知,深度学习模型中的参数一般从数百甚至数十亿不等,传统的CPU对庞大的网络计算能力有限,只有GPU才能让网络得以相对快速训练。对于具有很多层和节点的大型神经网络,较少其存储和计算成本变得至关重要,特别是对于一些实时应用,如在线学习、
增强学习以及自动驾驶。再比如将深度学习应用于移动端,如何让深度模型在移动设备上运行,也是模型压缩加速的一大重要目标。

目前有四类深度模型压缩方法:

  • 参数修剪和共享
  • 低秩因子分解
  • 转移/紧凑卷积滤波器
  • 知识蒸馏

基于参数修剪和共享的方法针对模型参数的冗余性,试图去除冗余和不重要的项。基于低秩因子分解的技术使用矩阵/张量分解来估计深度学习模型的信息参数。基于转移/紧凑卷积滤波器的方法设计了特殊的结构卷积滤波器来降低存储和计算复杂度。知识蒸馏方法通过学习一个蒸馏模型,训练一个更紧凑的神经网络来重现一个更大的网络的输出。
其中使用转移/紧凑卷积核方法仅支持卷积层。其他三种方法可用于全联接层和卷积层的CNN。
关于参数修剪和共享
根据减少冗余的方式,可以分为三类:模型量化和二进制化、参数共享和结构化矩阵。
a 量化和二进制化:网络量化通过减少表示每个权重所需的比特数来压缩原始网络。压缩流程:修剪、量化和霍夫曼编码。修剪减少了需要编码的权重数量,量化和霍夫曼编码减少了用于每个权重编码的比特数。对于大多数是0的矩阵使用稀疏表示,进一步降低空间冗余,这种机制不会带来准确率损失。但是二进制化方法会造成准确率损失
b 剪枝和共享:网络剪枝和共享起初是解决过拟合问题的,现在更多被用于降低网络复杂度。
c 设计结构化矩阵:约束条件会降低精确,很少用到。

26、什么是residual learning?说说你的理解
27、residual learning所说的residual和GBDT中的residual有什么区别?

问题2中,我们知道GBDT是利用损失函数的负梯度在当前模型的值作为算法中残差的近似值,来拟合一棵决策树。通过沿着负梯度不断拟合残差来使得整体的偏差尽可能的沿着Loss最小的方向走,直至达到最优收敛。
研究发现,随着神经网络层数增加,网络的表达能力增强了,模型的精度反而降低了,这不再是过拟合问题,而是网络退化。然而这并不符合逻辑,因为深层网络在训练时,可以是在浅层网络的函数上加上一个恒等变换。而深层网络显然没有把这种恒等变换学习到。因此有了残差网络(Resnet)。
从正向传播上来看,引入恒等变换可以使网络参数调整作用更大。这个地方引用下知乎回答:“F是求和前网络映射,H是从输入到求和后的网络映射。比如把5映射到5.1,那么引入残差前是F’(5)=5.1,引入残差后是H(5)=5.1, H(5)=F(5)+5, F(5)=0.1。这里的F’和F都表示网络参数映射,引入残差后的映射对输出的变化更敏感。比如s输出从5.1变到5.2,映射F’的输出增加了1/51=2%,而对于残差结构输出从5.1到5.2,映射F是从0.1到0.2,增加了100%。明显后者输出变化对权重的调整作用更大,所以效果更好。残差的思想都是去掉相同的主体部分,从而突出微小的变化,看到残差网络我第一反应就是差分放大器。”
实验证明,残差块往往需要两层以上,单单一层的残差块并不能起到提升作用。详情可以参考:resnet网络原理
这么看来,residual learning中的学习残差函数来克服深度神经网络中的网络退化现象的。

28、FFM和FTRL有过了解吗?

我之前的博客中提到过FFMFTRL

29、你对现在Deep Learning的发展和遇到的问题有什么看法?

猜你喜欢

转载自blog.csdn.net/wyisfish/article/details/80012148