时间为友,记录点滴。
为什么是简简介呢?因为我理解也不深。记录一下我的认知,如果有错误,敬请指教。
AdaBoost,是英文"Adaptive Boosting"(自适应增强)的缩写,是一种机器学习方法。我们在介绍SVM的时候,就提到过OpenCV已经支持了很多机器学习的算法,其中就有Boosting。我们可以在官方介绍中看一看:
cv::ml::Boost Class Referencedocs.opencv.org网上介绍Adaboost的琳琳总总,看来我们这个行当先行的大牛们遍地都是。可如果直接就进入源码或者手撕公式,难免吓退了进阶者。我希望能以一个普通人的身份先了解一下什么是Adaboost。
了解我们专栏的同学们肯定知道一个工科生想要干什么。要了解Adaboost首先要从Boosting下手。
1. 啥是Boosting?
Boosting直译过来就是加速/提升的意思,在机器学习中特指提升算法。
那么怎么理解加速/提升呢?加速上升的对象是什么呢?这一切都要从集成学习开始说起:
1.1 集成学习
1.1.1 强学习和弱学习
对于已经了解过机器学习的其中之一SVM的我们来说,肯定已经对分类算法有了一定的了解。如果我们把SVM看做是“很厉害”的分类器算法的话,那肯定有“不厉害”的分类算法,在机器学习领域,我们把“很厉害”和“不厉害”起个专业名词:
- 强学习:别准确率很高并能在多项式时间内完成的学习算法;
- 弱学习:识别错误率小于1/2,即准确率仅比随机猜测略高的学习算法;
好了,之所以把弱学习叫做“不厉害”的算法,而不是“很菜”的学习算法,他们的根本区别是弱学习一定要比随机猜测的准确率要高一些。
正所谓“三军易得,一将难求”,如果有什么办法能够将容易得到的弱学习方法转变成强学习方法就好了。之前,人们总是以为强学习和弱学习之间隔着无法逾越的鸿沟,但是弱学习这在集成学习这里就有可能完成蜕变。
1.1.2 集成学习概述
集成学习(ensemble learning)它本身不是一个单独的机器学习算法,而是通过构建并结合多个机器学习器来完成学习任务,所谓三个臭皮匠赛过诸葛亮嘛。集成学习可以用于分类问题集成,回归问题集成,特征选取集成,异常点检测集成等等,可以说所有的机器学习领域都可以看到集成学习的身影。
还是太空洞?画个简图:
从这个图中块就可以看出来,对于集成学习来说,两个概念最重要:
- 个体(弱)学习器
- 结合策略
下面我们就从这两个方向入手,看看集成学习的内涵。
1.1.3 个体学习器
怎么理解个体学习器呢?我们了解过的SVM就是一个分类学习器。对于集成学习来说,个体学习器不会区分强、弱学习器(毕竟强者还可以更强)。但是,选择什么类型的学习器却掌握在我们手里,可以根据选择个体学习器的类型分成如下两类:
- 同质:
所有的个体学习器都是一个种类。比如都是神经网络的?或者都是支持向量机的?
- 异质:
不是所有个体学习器都是一个种类。比如我们有一个分类问题,对训练集采用支持向量机个体学习器,逻辑回归个体学习器和朴素贝叶斯个体学习器来学习,再通过某种结合策略来确定最终的分类强学习器
目前来说,同质个体学习器的应用是最广泛的,一般我们常说的集成学习的方法都是指的同质个体学习器(同质个体学习器使用最多的模型是CART决策树和神经网络)。同质个体学习器按照个体学习器之间是否存在依赖关系可以分为两类:
- 强依赖:
个体学习器之间存在强依赖关系,一系列个体学习器基本都需要串行生成,代表算法是boosting系列算法;
- 弱依赖:
个体学习器之间不存在强依赖关系,一系列个体学习器可以并行生成,代表算法是bagging和随机森林(Random Forest)系列算法。
有点乱?没关系,看下图:
1.1.4 结合策略
有人的地方,就有江湖。我们既然知道了何为个体学习器,也大概知道了如何选择个体学习器,那么下一步就是要让这些个体学习器行程组织,才有战斗力,形成蜕变。
靠什么呢?专业名词叫“结合策略”!
我们假定选择了N个弱学习器是
1、平均法:
对于数值类的回归预测问题,通常使用的结合策略是平均法,也就是说,对于若干个弱学习器的输出进行平均得到最终的预测输出。即便是平均法,可以分为:
- 算术平均
- 加权平均
其中
2、投票法:
对于分类问题的预测,我们通常使用的是投票法。假设我们的预测类别是
- 多数投票法:
也就是我们常说的少数服从多数,也就是T个弱学习器的对样本x的预测结果中,数量最多的类别ci为最终的分类类别。如果不止一个类别获得最高票,则随机选择一个做最终类别。
- 绝对多数投票法:
也就是我们常说的要票过半数。在相对多数投票法的基础上,不光要求获得最高票,还要求票过半数。否则会拒绝预测。
- 加权投票法:
和加权平均法一样,每个弱学习器的分类票数要乘以一个权重,最终将各个类别的加权票数求和,最大的值对应的类别为最终类别。
3、学习法:
不管是平均法还是投票法,他们的处理都是基于个体学习器的输出结果做文章,每个个体学习器之间都是并行、独立的关系,如果能让个体学习器之间建立正反馈关系就好了。
嗯,学习法就是这么来的。比如stacking,我们不是对弱学习器的结果做简单的逻辑处理,而是再加上一层学习器,也就是说,我们将训练集弱学习器的学习结果作为输入,将训练集的输出作为输出,重新训练一个学习器来得到最终结果。
在这种情况下,我们将弱学习器称为初级学习器,将用于结合的学习器称为次级学习器。对于测试集,我们首先用初级学习器预测一次,得到次级学习器的输入样本,再用次级学习器预测一次,得到最终的预测结果。
1.2 Boosting
了解过集成学习的概念之后,再去理解Boosting就容易多了。
首先,Boosting是集成算法的一种,所以它的所用就是把弱学习器变成强学习器的一种方法;
其次,我们有提到过Boosting是一种强依赖的个体学习器,所以在选择个体学习器的时候一要保证学习器的同类,二是指明了个学习器之间的是有依赖关系的;
1.2.1 官方定义
提升方法(Boosting),是一种可以用来减小监督式学习中偏差的机器学习算法。
Valiant和 Kearns提出了弱学习和强学习的概念后,首次提出了 PAC学习模型中弱学习算法和强学习算法的等价性问题,即任意给定仅比随机猜测略好的弱学习算法 ,是否可以将其提升为强学习算法 ? 如果二者等价 ,那么只需找到一个比随机猜测略好的弱学习算法就可以将其提升为强学习算法 ,而不必寻找很难获得的强学习算法。1990年, Schapire最先构造出一种多项式级的算法 ,对该问题做了肯定的证明 ,这就是最初的 Boosting算法。
需要指出的是,Boosting算法发展到现在早已不是一个算法,而是一类算法。
1.2.2 实现框图
好了,我们知道官方定义一般都是看不懂的大实话。不过,我们可以看如下框图,从集成学习的角度理解一下:
其中:
- 总的样本集
:代表所有可监督学习的数据;
-
:表示对总样本集的加权值,这个加权值是由它的上一层个体学习器的学习误差率获得的,即和的误差率相关;
-
:表示经过加权后的样本集;
-
:表示个体学习器;
-
:对应集成学习中的结合策略;
-
:表示最终得到的强学习器;
从这个图就容易理解了,Boosting就是一种强依赖的个体学习器+加权(平均)的一类集成学习算法,通过这种反馈加权的方法构造样本集给各个弱学习器,以达到把弱学习器变成强学习器的目的。
1.2.3 为什么要搞加权
在引入一些简单的公式之前,我相信很多人都会跟我一样有这么一个疑问,为什么是要给总样本集搞加权?搞加权后的样本集是什么意思?
话不多说看例子:
如果把Android源码看做训练集,把驱动工程师、Tuning工程师、系统工程师、应用工程师当做弱学习器,那么如何完成一个Camera Feature(强学习器)呢?
- 驱动工程师完成Driver部分,完成后任务转交Tuning工程师;
- 这个时候Tuning工程师可以不关心Android 源码部分了,因为驱动工程师已经完成了啊,而且比自己专业(误差率小)多啦,Tuning工程概念是完成HAL部分,然后把任务转交系统工程师;
- 这个时候系统功臣是就可以Driver和HAL都不用关心啦,安心处理FW即可,相当于对Driver和HAL做了0的加权,屏蔽这些数据不让系统工程师处理,系统工程师完成FW的部分,转交应用工程师;
- 对于应用工程师来说,其他模块都被加权屏蔽了,他只需要完成自己最在行的APP就可以了,千万别改别人的模块;
那么经过这些步骤之后,就完成了完整的Camera Feature。
1. 如果让任何一位工程师来搞定Camera Feature都几乎是不可能的,但是任何一位工程师却比一般人厉害那么一点点,所以一个方向的工程师就是一个弱学习器;
2. 如果让所有的工程师都可以修改别人的代码,那么最终得到的Feature一定是Bug多成马了的,所以,用Boosting加权的方式规定大家做自己擅长的事才是王道;
1.2.4 理论支撑
有人告诉我,我每写一个公式,我的读者就会少一半。所以,我还是尽量少写(其实是我数学也不好)。
Boosting算法要涉及到两个部分,加法模型和前向分步算法。
- 加法模型
加法模型就是说强分类器由一系列弱分类器线性相加而成,即集成学习中的结合策略。一般组合形式如下:
其中,
- 前向分步
前向分步就是说在训练过程中,下一轮迭代产生的分类器是在上一轮的基础上训练得来的,即集成学习中的如何构成强依赖关系。也就是可以写成这样的形式:
2. 啥是AdaBoost?
2.1 Wiki定义
AdaBoost,是英文" Adaptive Boosting"( 自适应增强)的缩写,是一种机器学习方法,由Yoav Freund和Robert Schapire提出。AdaBoost方法的自适应在于: 前一个分类器分错的样本会被用来训练下一个分类器。AdaBoost方法对于噪声数据和异常数据很敏感。但在一些问题中,AdaBoost方法相对于大多数其它学习算法而言,不会很容易出现过拟合现象。AdaBoost方法中使用的分类器可能很弱(比如出现很大错误率),但只要它的分类效果比随机好一点(比如两类问题分类错误率略小于0.5),就能够改善最终得到的模型。而错误率高于随机分类器的弱分类器也是有用的,因为在最终得到的多个分类器的线性组合中,可以给它们赋予负系数,同样也能提升分类效果。
AdaBoost方法是一种迭代算法,在每一轮中加入一个新的弱分类器,直到达到某个预定的足够小的错误率。每一个训练样本都被赋予一个权重,表明它被某个分类器选入训练集的概率。如果某个样本点已经被准确地分类,那么在构造下一个训练集中,它被选中的概率就被降低;相反,如果某个样本点没有被准确地分类,那么它的权重就得到提高。通过这样的方式,AdaBoost方法能“聚焦于”那些较难分(更富信息)的样本上。在具体实现上,最初令每个样本的权重都相等,对于第k次迭代操作,我们就根据这些权重来选取样本点,进而训练分类器Ck。然后就根据这个分类器,来提高被它分错的的样本的权重,并降低被正确分类的样本权重。然后,权重更新过的样本集被用于训练下一个分类器Ck。整个训练过程如此迭代地进行下去。
2.2 跟Boosting有什么关系?
首先可以肯定的是,Adaboost是Boosting的一种改进实现,好在我们已经对Boosting有了大概的了解,这样我们只要从两个方面就可以了解Adaboost。它跟传统Boosting比差异是什么?到底改进了什么?
2.2.1 框架差异
我觉得有了Boosting/集成学习这么长的铺垫,看懂wiki定义应该问题不大了。仔细阅读下来去对比我们聊过的Boosting,貌似没有什么差异嘛。。。
镇定,分析这个问题还是要回归集成学习的本质。个体学习器+结合策略。
- 个体学习器的差异
看官方介绍:
1990年, Schapire最先构造出一种多项式级的算法 ,对该问题做了肯定的证明 ,这就是最初的 Boosting算法。一年后 ,Freund提出了一种效率更高的Boosting算法。但是,这两种算法存在共同的实践上的缺陷 ,那就是都要求事先知道弱学习算法学习正确的下限。1995年 , Freund和 schap ire改进了Boosting算法 ,提出了 AdaBoost (Adaptive Boosting)算法,该算法效率和 Freund于 1991年提出的 Boosting算法几乎相同 ,但不需要任何关于弱学习器的先验知识 ,因而更容易应用到实际问题当中。之后 , Freund和 schapire进一步提出了改变 Boosting投票权重的 AdaBoost . M1,AdaBoost . M2等算法 ,在机器学习领域受到了极大的关注。
原来是在实践过程中用不用关心弱学习器的学习正确率的下限。
我的注释:
这段内容来自百度百科,得到的结论也是基于官方介绍的内容。但是,这个差异我感觉并不适合于本篇文章讲解的Boosting和Adaboost。原因是制作以要关心下限就是因为没有为Boosting引入加权的概念,但是很明显,我们介绍的Boosting已经引入加权(数据集加权+个体学习器加权)。所以我认为这个差异很可能是因为历史原因造成的,即在Boosting发展的过程中已经弥补了这点。那么在个体学习器上, 并没有什么差异。
- 结合策略的差异
需要指出的是,在OpenCv中Adaboost也支持4种算法:
即:
- DAB:
Discrete AdaBoost
- RAB:
Real AdaBoost. It is a technique that utilizes confidence-rated predictions and works well with categorical data
- LB:
LogitBoost. It can produce good regression fits.
- GAB:
Gentle AdaBoost. It puts less weight on outlier data points and for that reason is often good with regression data.
我们以DAB为例,看看它采用了什么结合策略?
我的天,貌似也是一样的!都是加权(平均)。。。
如果是这个结果,只能说明我的方向没搞对。Boosting本来就是一个算法集合的概念,那么Adaboost肯定是套用了Boosting的框架。如果是框架一样,就一定是有哪些实现方式不一样!
2.2.2 实现差异
我们再回过头,看看Boosting的实现:
- 加法模型:
- 前向分步:
会不会在这里的有差异呢?那我们只能去实现细节里面看看了!
先说结论: 由于采用的损失函数不同,Boosting算法也因此有了不同的类型,AdaBoost就是损失函数为指数损失的Boosting算法。
2.3 实现细节
2.3.1 文字描述
- 给定训练样本集X,共有m个
元素,其中和分别对应正例样本和负例样本;且 N为训练的最大循环次数(个体学习器个数);
- 初始化样本权重为1/m ,即为训练样本的初始平均概率分布;
- 开始迭代:
- 训练样本的概率分布相当下,训练弱分类器;
- 计算弱分类器的错误率;
- 选取合适阈值,使得误差最小;
- 更新样本权重(具体训练过程中,如果某个样本点已经被准确地分类,那么在构造下一个训练集中,它的权值就被降低;相反,如果某个样本点没有被准确地分类,那么它的权值就得到提高。),进入下一轮迭代;
经N次循环后(N个弱分类器),按更新的权重叠加,最终得到的强分类器。
2.3.2 公式描述
在上面的文字描述中,其实我们埋下了4个坑,也是所有Boosting算法在实践中需要解决的具体问题:
- 如何计算分类误差率
?
- 如何更新训练数据的样本权重
?
- 如何得到弱学习器权重系数
?
- 使用何种结合策略?
我们来看一看Adaboost怎么解决的。
- 预设条件
假设我们的训练集样本是:
训练集的在第k个弱学习器的样本权重系数为:
- 分类误差率
分类问题的误差率很好理解和计算。由于多元分类是二元分类的推广,这里假设我们是二元分类问题,输出为{-1,1},则第k个弱分类器
- 样本权重
如何更新样本权重D。假设第k个弱分类器的样本集权重系数为
这里
从
- 弱学习器的权重系数
接着我们看弱学习器权重系数,对于二元分类问题,第k个弱分类器
(注意这个权重系数的定义,指数损失的由来)
为什么这样计算弱学习器权重系数?从上式可以看出,如果分类误差率
- 结合策略
Adaboost分类采用的是加权平均法,最终的强分类器为:
系数
完美!
既然OpenCV提供了Boost类,不如试一试它的效果:
Coding...