百面机器学习 之 集成学习

问题1. 什么是Boosting和Bagging,他们各自有什么特点

        Boosting的主要思想就是 将基分类器层层叠加,每一层训练的时候对前一层基分类器分错的样本给予更高的权重进行训练,每个分类器之间是采用串行的方式,各个分类器之间有依赖。测试的时候各层的分类器的结果的加权得到最终结果。

        Bagging的主要思想就是 也是训练基分类器,但是和Boosting不一样的是,Bagging的训练器之间是没有依赖的,可以进行并行训练,所以在训练之前,要划分一下数据集(数据集之间可能有交集)每一个基分类器可以单独自己学习样本学到的内容。最后测试的时候,每个单独的基分类器都要做出判断,最后通过投票的方式做出最后的决策。

        书上还有一个说法,也是讲得特别ok!刚好master讲了

        high bias就是偏离正确值,high variance就是太贴合样本分布了,导致过拟合

        boosting就是通过不断纠正错误从而一步一步减少bias

        bagging就是通过分而治之,综合出多个模型来减少方差(通过投票的方式)

这里直接插问题四进来了:

问题四:偏差和方差

        Bias(偏差):指的是由所有采样得到的大小为m的训练数据集训练处的所有模型输出的平均值和真实模型输出之间的偏差

        Variance(反差):指的是由所有采样得到的大小为m的训练数据集训练出的所有模型的输出的方差。换句话说就是如果一个模型在可获得的样本上有较小的方差,说明它对不同数据集的敏感度不高,可以期望它对新数据集的预测效果比较稳定。反映出稳定程度,如果高方差那就跳来跳去了,也就是过拟合了。

        然后解释一下为啥boosting就是降低bias,而bagging就是降低var呢?

        Bagging对样本重采样,对每一重采样得到的子样本集训练一个模型,最后取平均。由于子样本集的相似性以及使用的是同种模型,因此各模型有近似相等的bias和variance。由于

E \frac{\sum X_i}{n} = E[X_i]

        所以Bagging后的bias和单个模型的bias都是差不多的,但是反观var

var(\frac{\sum X_i}{n}) = var(X_i)

        也就说说方差缩小到原来的n分之1,当然这个是建立在不同的模型之间是完全独立的,但是我们知道Bagging的思想怎么着都会多多少少不独立的。所以这个描述不是特别严谨,但怎么着多多少少还是会降低方差的。

        而Boosting则是通过计算弱分类器的错误或者残差作为下一个分类器的输入,这个过程就是在不断地减少损失函数了,所以就是一个在不断减少bias的过程。

问题2. 集成学习的步骤和例子

        其实之前就已经写过Adaboost和GBDT的文章,但是这里看书感觉比较清晰,还是根据书上的来吧。

        集成学习一般都是以下三个步骤

        1. 找到误差互相独立的基分类器

        2. 训练这些基分类器

        3. 合并分类器的结果

        其中合并分类器有两种方法:第一种是上面说的voting,占比多的那个类别作为输出类别。第二种是stacking,这种是用串行的方式,把前一个基分类器的结果输出到下一个分类器,然后将所有基分类器的输出结果相加作为最终的输出。

        注意啊这里要注意!上面说的Boosting和Bagging是模型的训练方式,也就是对应步骤的第二点。然后voting和stacking说的是合并分类器的方式,也就是步骤的第三点。这里要区分开呀!

        下面这个例子就是书上的AdaBoost的例子,和我之前写过的一样。

        可以看出,AdaBoost就是用boosting的思想,提高错误样本的权重从而降低bias,然后最后用voting的方式去合并分类器。

        GBDT就是boosting的思想,他的目标就是拿前一科树的残差去做处理,做拟合,都是需要前人栽树后人乘凉的思想。

问题三:常用的基分类器是什么?为什么  

        最常用的基分类器是决策树:书上给出了原因

        1. 决策树可以非常容易地调整权重,马上应用到下一次的训练当中

        2. 决策树的表达能力和泛化能力都可以通过树的高度(层数)去调整

        3. 数据样本的扰动对决策树影响最大,这么不稳定其实就真的非常适合作为基分类器,也就是不同样本对应生成的基分类器的随机性比较大。

问题四:可否将随机森林中的基分类器,由决策树替换为别的线性分类器/KNN?为什么?

        首先要知道什么随机森林,这个好像没有认真写过

        随机森林主要是应用了Bagging的思想,将若干个弱分类器的分类结果进行投票选择,从而组成一个强分类器。

        按照上面我们提到的Bagging思想,下面来说一下每棵树是怎么生成的:引用大佬的文章

        每棵树的按照如下规则生成:

  1)如果训练集大小为N,对于每棵树而言,随机且有放回地从训练集中的抽取N个训练样本(这种采样方式称为bootstrap sample方法),作为该树的训练集;

  从这里我们可以知道:每棵树的训练集都是不同的,而且里面包含重复的训练样本(理解这点很重要)。

  为什么要随机抽样训练集?

  如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的,这样的话完全没有bagging的必要;

  为什么要有放回地抽样?

  我理解的是这样的:如果不是有放回的抽样,那就每棵树的训练数据集都是不一样,这就会导致有偏估计的发生,而随机森林最后分类取决于多棵树(弱分类器)的投票表决,这种表决应该是在每一棵树都取于同一个训练集的情况下发生的,因此使用完全不同的训练集来训练每棵树这样对最终分类结果是没有帮助。

  2)如果每个样本的特征维度为M,指定一个常数m<<M,随机地从M个特征中选取m个特征子集,每次树进行分裂时,从这m个特征中选择最优的;

  3)每棵树都尽最大程度的生长,并且没有剪枝过程。

  一开始我们提到的随机森林中的“随机”就是指的这里的两个随机性。两个随机性的引入对随机森林的分类性能至关重要。由于它们的引入,使得随机森林不容易陷入过拟合,并且具有很好得抗噪能力(比如:对缺省值不敏感)。

         我们之前提到过:bagging就是通过分而治之,综合出多个模型来减少方差(通过投票的方式)

        Bagging所采用的基分类器,最好就是本身对样本分布比较敏感的(也就是不稳定的分类器),这样才可以通过Bagging的思想去获得更好的分类结果。这里可能说得有点不通,换句话来说就是我bagging最大能耐就是集百家所长,所以我就要求我有各种各样的基分类器,这样我才能更好地cover全方位的情况,然后就交给Bagging自己捣鼓,自己投票决定这个应该是啥,所以我们需要不稳定的基分类器来做处理,这里提到的KNN和线性分类都是比较稳定的,本身方差就不大,所以就算用了Bagging也不能有更好的表现,甚至因为Bagging两个随机的采样(引用的地方提到了什么是两个随机),导致训练构成中更难收敛,从而造成bias更大了。

问题五: GBDT的基本原理是什么

        直接引用书上的话了,细节可以看之前的文章进行补充,GBDT是Boosting的一类算法,根据当前模型损失函数的负梯度来训练新加入的弱分类器,然后将训练好的弱分类器以累加的形式结合到现有的模型中。在每一轮的迭代中,首先计算出当前模型在所有样本上的负梯度,然后以该值为目标训练一个新的弱分类器进行拟合 并计算 该弱分类器的权重,最终实现对模型的更新。

问题六:梯度提升和梯度下降的区别和联系是什么

        这个问题也是问得非常好呀!我们再来复习一下梯度下降为什么是负梯度代表着loss下降最快的方向。

        假设我们有一个loss function:L(\theta_t) 并且在\theta_{t-1} 做一个一阶的泰勒展开:

        于是有:

L(\theta_t) = L(\theta_{t-1}+\bigtriangleup \theta) = L(\theta_{t-1}) + \bigtriangleup \theta * L'(\theta_{t-1})

        移项:

        L(\theta_{t-1}+\bigtriangleup \theta) - L(\theta_{t-1}) = \bigtriangleup \theta * L'(\theta_{t-1})

        现要使得: L(\theta_t)<L(\theta_{t-1}),也就是loss越来越大

        其中 : \bigtriangleup \theta * L'(\theta_{t-1}) 是函数值的变化量,我们要注意的是L'(\theta_{t-1}) 和 \bigtriangleup \theta 都是向量(多元变量),所以这个 \bigtriangleup \theta * L'(\theta_{t-1}) 就是一个向量的点积,而向量进行点积的最大值,就是两者共线(同在一条直线,而且是同一个方向)的时候,点积取值达到最大,而这个点积值,就是从L(\theta_{t-1}) 到L(\theta_t) 的取值,就是上升量(注意哈这里是L(\theta_t)<L(\theta_{t-1})

        而 L'(\theta_{t-1}) 就是代表函数在 \theta_{t-1} 的梯度,我们在上一段已经证明了,\bigtriangleup \thetaL'(\theta_{t-1})方向相同的时候,是函数 L(\theta) 上升得最快的。这恰巧不也证明了 梯度的负方向就是下降的最快方向吗,这就应证了负梯度代表着loss下降最快的方向的结论了。

        下一步我们看梯度提升是究竟怎么一回事,其实梯度提升在GBDT里面就说过一回,它的主要思想是通过拟合残差去获得一个弱分类器进行累加,从而达到缩小loss的目的。

        对于模型的损失函数L(y,F(x))  ,为了能够求解出最优的函数 F^*(x) ,首先设置初始值为: F_0(x) = f_0(x)

        以函数F(x) 作为一个整体,和梯度下降法的更新过程一致,假设经过T次迭代最后函数(模型):

F^*(x)= \sum^T_{t=0}f_t(x)

        其中f_t(x) : 

f_t(x) = -\alpha_t * g_t(x) = -\alpha_t*\left [ \frac{\partial L(y,F(x))}{\partial F(x)} \right ]

        可以看到,这里的梯度变量是一个函数,是在函数空间上求解,而我们以前梯度下降算法是在多维参数空间中的负梯度方向,变量是参数。为什么是多维参数,因为一个机器学习模型中可以存在多个参数。而这里的变量是函数,更新函数通过当前函数的负梯度方向来修正模型,使模型更优,最后累加的模型为近似最优函数。

        ok那为什么前面引出了残差呢?当损失函数是一个平方误差函数时,刚好残差就是损失函数的梯度方向,因此我们可以推广到其他不是平方误差的损失函数,也就是说,梯度提升算法是一种梯度下降算法,只需要更改损失函数和梯度就能将其推广。

        对于平方损失函数拟合的是残差;对于一般损失函数,拟合的就是残差的近似值。

        所以 梯度提升和梯度下降的区别和联系是什么:

        联系:

        两者都是在每一轮迭代中,利用损失函数相对于模型的负梯度方向的信息来对当前模型进行更新

        区别:

        只不过在梯度下降中,模型是以参数化形式表示,从而模型的更新等价于参数的更新。而在梯度提升中,模型并不需要进行参数化表示,而是直接定义在函数空间中,从而大大扩展了可以使用的模型种类。(梯度下降是对参数更新,而梯度提升是对模型更新)

问题七:XGBoost和GBDT的区别和联系是什么?

       1. XGBT显示地在创建树的时候就在已经引入了正则项去控制模型的复杂度,防止过拟合,而GBDT则需要做建树后做剪枝的操作。

        2. 精度更高:GBDT用的是损失函数的一阶导数信息,而XGBoost是对损失函数进行二阶泰勒展开,同时使用了一阶和二阶泰勒展开。

        3. 灵活性更强:GBDT采用CART作为基分类器,而XGBoost支持多种类型的基分类器,这个时候xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。另外,Xgboost支持自定义损失函数,只要损失函数有一二阶导数。

        4. Shrinkage(缩减):相当于学习速率。这个主要是为了削弱每棵树的影响,让后面有更大的学习空间,学习过程更加的平缓

        5. 传统的GBDT在每轮迭代时使用全部的数据, XGBOOST则采用了与随机森林相似的策略, 支持对数据进行采样。

                

                

Guess you like

Origin blog.csdn.net/Francis_s/article/details/122227247