集成学习的基本原理是,训练多个“个体学习器”或者叫基分类器,基学习器。然后用某种策略将它们结合起来,最后可以产生比单一学习器优越得多的性能。
集成学习的基本原理是什么呢?假设对于每个基分类器,错误率有:
并且 假设分类器之间之互相独立的,那么最终的错误率为:
可以看到当错误率 ϵ>0.5 随着个体分类器数目 T 的增大,最终的错误率会趋向于0。我们把分类正确率稍大于0.5,也就是比瞎猜好一点的分类器称为弱分类器。按照上面的分析,只要基分类器不比弱分类器差,最终我们的集成的结果都可以任意好!
但是上面有一个非常重要的假设条件,各个分类器之间需要相互独立,但是实际中基分类器都是由同一个数据集中训练出来的,不可能完全独立,所以如何从一个数据集中训练出来具有“多样性”的基学习器是非常重要的,但是其实多样性和准确性是相互矛盾的。
按照基学习器的生成方式,目前的集成学习的方法分成两大类。一种是学习器之间是串行生成的,学习器互相之间有很强的依赖性,代表算法是Boosting。另一种是并行生成的学习器,学习器之间相关关系不大,代表算法是Bagging 和Random Forest(随机森林)。
下面介绍这两类算法
Boosting
首先介绍两个概念
“强可学习”:一个类,如果存在一个多项式的学习算法能够学习它,并且正确率很高,那么就称这个类是强可学习的。
“弱可学习”:一个类,如果存在一个多项式的学习算法能够学习它,但是正确率仅仅比随机猜测要好,那么就称这个类是弱可学习的。
那么问题来了,如果我们有了一个弱可学习的算法,如何把它提升成为一个强可学习的算法?这就是下面将要介绍的提升(boost)算法,代表算法是AdaBoost算法。
提升算法的基本原理是,开始的时候,我们给数据集所有数据以相同的权重。然后首先我们有一个弱分类器,分类之后,我们对分类错误的数据以更高的权重,这就产生了一个新的样本分布,在此基础上我们再生成一个基分类器,再重复以上步骤,直到分类器个数达到要求。之后把所有的分类器按照权重相加(这个权重在每一步单独计算),就得到最终的分类器。看不懂没关系,我理解的AdaBoost的基本原理就是,每训练一个基学习器都要对之前没有分类好的数据进行修正,最终达到我们的要求。
下面是AdaBoost的算法的描述
再仔细描述一下上面的步骤:
(1) 先初始化所有点的权值分布
注意这里的花写的D代表的是数据点的权重分布,脚标1代表第一次初始化得来的分布,这一点不要忘记,否则后面的证明等很容易糊涂。
(2)进入循环,不断执行以下四步,对于第t次循环
(a)根据具有权重分布 Dt 的数据集 D ,训练得到一个基学习器
(b)计算分类器 ht 在训练数据集上的分类误差率
注意这里面的求和的式子里是加权的,这里也体现出了权重的作用,如果一个点的权重较大,那么他一旦分错,对总的误差率影响也较大。
(c)计算 ht(x) 的系数
注意这里的系数是分类器的系数,最后按照系数将所有分类器相加的到最后的分类器
(d)更新数据集的权重分布
Zt 是一个规范化因子,使得 Dt+1 成为一个概率分布。在上一步中预测错误的点 yiht(xi)=−1 (因为是二分类,两个取值为1或者-1),这一次更新之后权重会增加。
(3)当循环结束后,我们把所有基分类器按照系数相加,得到
那么最终的分类器
下面证明一下AdaBoost,主要是证明 αt 和 D 的更新是怎么来的,不感兴趣的可以跳过
AdaBoost 证明
1.
当基分类器
ht(x)
基于权重分布
D
产生之后,我们要生成
ht
的权重
αt
,而
α
应该最小化
αtht
的指数损失函数(下面公式里面的
f(x)
代表的是数据集上的数据的类,这点要记住,不然容易糊涂)
注意上面这一步是把输出和预测值相等和不相等两种情况拆开来写的。然后令 ϵt=Px∼Dt(f(x)≠ht(x)) ,注意这里不是简单的错误率,注意脚标就知道,是将预测错误的数据点的权重相加。下面我们就可以得到上式等于:
指数损失函数是在AdaBoost中默认使用的损失函数,具体因为什么,我也不知道了。
可以看到指数损失函数是单调递增的凸函数,求它的极值点就能够得到最值点。我们对指数损失函数求导,可以得到
再令上式为0,可以得到
而这个正好就是上面的对 αt 的更新公式。
2.
下面介绍
Dt
是如何更新的,顺便介绍一下
ht
的一些性质。
当Adaboost获得
Ht−1=α1h1(x)+α2h2(x)+⋯+αt−1ht−1(x)
之后,假设已经对样本进行了权重的更新,现在我们要如何训练出一个
ht
来纠正前面的学习器所犯的错误,假设新的学习器能够最小化指数损失函数即
利用 f2(x)=h2t(x)=1 ,再利用泰勒展开可得:
上面这个式子有两点需要注意 1. 是相对于初始分布 D 求的均值 2. ht 前面是没有参数 α 的这也是我们的具体步骤,在每一步我们是直接先相对于上一步训练出来的分布求出一个学习器,再根据最小化指数损失函数的原则求出 αt
这时,理想的学习器为
也就是能够使总的损失函数最小化的学习器。
那么联系上面的式子可得
之所以能够这么写,我的理解是因为这个时候 Ht−1 是已知的,那么 Ex∼D[e−f(x)Ht−1(x)] 是一个常数,同理我在式子右边除以这个常数的期望值对式子本身也是没有影响的,那么可得
令
Dt
表示一个分布
这是第 t 个分布
之后接着我们就有了
注意变成了在 Dt 上的期望,这一步看不懂的话把期望公式展开就理解了。
再由于
f(x)h(x)=1−2I(f(x)≠h(x))
,可得理想的学习器为
也就是 ht(x) 在分布 Dt 下最小分类误差。这句话什么意思呢?记得我们最开始的 ht 的表达式么? ht(x)=argminhℓexp(Ht−1+ht|D) , 最小化的是在初始分布上总的学习器误差,但是最终我们得到了这个理想的学习器只需要在 Dt 上最小化分类误差就行!
然后由于已经有了
Dt
和
D
之间的关系就很容易得到
Dt
和
Dt+1
之间的关系
上面就是算法中对权重进行更新的的式子,可以看到, 预测错误的点的权重会变大 eαt ,预测正确的点的权重会变成原来的 e−αt
以上的证明完全来自周志华的《机器学习》,只是自己看的时候有点费劲,于是就想在看懂之后加上自己的想法记录下来,也就有了上面的记录,以供参考
Bagging和随机森林
前面说过串行产生基学习器的算法是AdaBoost ,并行产生学习器的是Bagging。Bagging和“袋子”没有关系,而是由Booststrap AGGregatING算法的缩写,其中boostrap是一种自主采样法(boostrap sampling)。主要步骤是,对于一个大小为m的样本集,我们从中取出一个样本,然后再放回去,之后再取,不断抽样直到总共得到m个样本。显然,这么抽样显然是有可能有样本被重复抽样,最后初始训练集中约有63.2%的样本会被选中到最终的采样集中。
我们按照这种采样方式得到
T
个含有m个样本的采样集,在这些采样集上分别训练出来
这种简单的Bagging方法是通过在样本上产生多样性,从而给予学习器之间独立性。
第二种算法叫做随机森林(Random Forest, RF),RF是Bagging的一种变体,基学习器是决策树,只是同时引入了属性的随机选择的算法。首先每个作为基学习器的决策树都很短,目前看到的很多都是只用决策树桩(只进行一次划分)就行。然后每次进行属性选择的时候是首先选择一个所有属性集 的子集,然后从这个子集中选择出最优的属性。通过这种方式引入属性的随机性。
可以看出随机森林的原理很简单,容易实现,但是实际上它的性能很好,被誉为“代表集成学习技术技术水平的方法”。相比于Bagging 随机森林的方法一般初始误差比较大,但是随着基学习器数量的增加,最后随机森林的效果往往比Bagging要好。
Stacking
Stacking是一种集成学习算法,很多算法可以视作它的特例,它也是一种很重要的结合策略。主要的原理也很简单,我们根据训练集训练出
T
<script id="MathJax-Element-247" type="math/tex">T</script>个初级学习器,这些初级学习器更多的时候是互不相同的,比如可能是决策树,神经网络等,当然也可能是相同的,比如都是决策树。然后我们还有一个次级学习器(也叫元学习器),我们拿所有的初级学习器的输出作为次级学习器的输入来训练次级学习器,最后得到一个总的学习器。
下图为流程的示意图
下面是算法的伪代码
算法本身不复杂,没有像AdaBoost那样的公式。就是在训练中,要注意为了防止过拟合,不能直接使用初级学习器的训练集产生次级学习器的训练集,而要使用交叉验证法,对初始的训练集进行划分,训练集用来训练初级学习器,验证集用来产生次级训练集。
Stacking是一种比较重要的思想,加入我们有一个学习器效果不是很好,我们想要提升它的效果,那我们可以用它和其他的学习器集成起来,从而达到减小误差提升效果的目的。
注:文中图片来自袁博老师《数据挖掘:理论与算法》ppt.