集成学习值Adaboost算法原理和代码小结(转载)
目录
在集成学习原理小结中,我们讲到了集成学习按照个体学习器之间是否存在依赖关系可以分为两类:
- 第一个是个体学习器之间存在强依赖关系;
- 另一类是个体学习器之间不存在强依赖关系。
前者的代表算法就是提升(boosting)系列算法。在boosting系列算法中, Adaboost是最著名的算法之一。Adaboost既可以用作分类,也可以用作回归。本文就对Adaboost算法做一个总结。
一 回顾boosting算法的基本原理
AdaBoost是典型的Boosting算法,属于Boosting家族的一员。在说AdaBoost之前,先说说Boosting提升算法。Boosting算法是将“弱学习算法“提升为“强学习算法”的过程,主要思想是“三个臭皮匠顶个诸葛亮”。一般来说,找到弱学习算法要相对容易一些,然后通过反复学习得到一系列弱分类器,组合这些弱分类器得到一个强分类器。Boosting算法要涉及到两个部分,加法模型和前向分步算法。加法模型就是说强分类器由一系列弱分类器线性相加而成。一般组合形式如下:
其中, 就是一个个的弱分类器,是弱分类器学习到的最优参数, 就是弱学习在强分类器中所占比重, 是所有和 的组合。这些弱分类器线性相加组成强分类器。
前向分步就是说在训练过程中,下一轮迭代产生的分类器是在上一轮的基础上训练得来的。也就是可以写成这样的形式:
由于采用的损失函数不同,Boosting算法也因此有了不同的类型,AdaBoost就是损失函数为指数损失的Boosting算法。
在前面一节,我们已经讲到了boosting算法系列的基本思想,如下图:
从图中可以看出,Boosting算法的工作机制是首先从训练集用初始权重D(1)训练出一个弱学习器1,根据弱学习的学习误差率表现来更新训练样本的权重,使得之前弱学习器1学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的弱学习器2中得到更多的重视。然后基于调整权重后的训练集来训练弱学习器2.,如此重复进行,直到弱学习器数达到事先指定的数目T,最终将这T个弱学习器通过集合策略进行整合,得到最终的强学习器。
在上图中有几个具体的问题我们没有详细说明。
- 如何计算分类误差率e?
- 如何得到弱学习器权重系数(即上式中的)?
- 如何更新训练数据的样本权重D?
- 使用何种结合策略?
只要是boosting大家族的算法,都要解决这4个问题。那么Adaboost是怎么解决的呢?
二 Adaboost算法的基本思想
我们这里讲解Adaboost是如何解决上面4个问题的。
假设我们的训练集样本是:
训练集的在第k个弱学习器的样本权重系数为:
注意:在初始化第一个弱分类器输出权重时,我们假设训练集样本具有均匀的权值分布,即每个训练样本在第一个弱分类器的学习中作用相同,这一假设保证可以在训练集样本上学习第一个弱分类器。
首先我们看看Adaboost的分类问题。
分类问题的误差率很好理解和计算。由于多元分类是二元分类的推广,这里假设我们是二元分类问题,输出为{-1,1},则第k个弱分类器在训练集上的分类误差率为:
接着我们看弱学习器权重系数,对于二元分类问题,第k个弱分类器的权重系数为:
为什么这样计算弱学习器权重系数?从上式可以看出,如果分类误差率越大,则对应的弱分类器权重系数越小。也就是说,误差率小的弱分类器权重系数越大。具体为什么采用这个权重系数公式,我们在讲Adaboost的损失函数优化时再讲。
第三个问题,如何更新样本权重D。假设第k个弱分类器的样本集权重系数为,则对应的第k+1个弱分类器的样本权重系数为:
这里是规范化因子:
从计算公式可以看出,如果第i个样本分类错误,则,导致样本的权重在第k+1个弱分类器中增大,如果分类正确,则权重在第k+1个弱分类器中减少.不改变所给的训练集数据,通过不断的改变训练样本的权重,使得训练集数据在弱分类器的学习中起不同的作用。具体为什么采用这个样本权重更新公式,我们在讲Adaboost的损失函数优化时再讲。
最后一个问题是集合策略。Adaboost分类采用的是加权平均法,最终的强分类器为:
系数表示了弱分类器的重要性,这里所有之和并不为1,的符号决定实例的类,的绝对值表示分类的置信度。
接着我们看看Adaboost的回归问题。由于Adaboost的回归问题有很多变种,这里我们以Adaboost R2算法为准。
我们先看看回归问题的误差率的问题,对于第k个弱学习器,计算他在训练集上的最大误差:
然后计算每个样本的相对误差
这里是误差损失为线性时的情况,如果我们用平方误差,则,如果我们用的是指数误差,则
最终得到第k个弱学习器的 误差率:
我们再来看看如何得到弱学习器权重系数。这里有:
对于更新更新样本权重D,第k+1个弱学习器的样本集权重系数为:
这里是规范化因子:
最后是结合策略,和分类问题稍有不同,采用的是对加权的弱学习器取中位数的方法,最终的强回归器为:
其中,是所有的中位数。
三 AdaBoost分类问题的损失函数优化
上面我们讲到了分类Adaboost的弱学习器权重系数公式和样本权重更新公式。但是没有解释选择这个公式的原因,让人觉得是魔法公式一样。其实它可以从Adaboost的损失函数推导出来。
从另一个角度讲,Adaboost是模型为加法模型,学习算法为前向分步学习算法,损失函数为指数函数的分类问题。
模型为加法模型好理解,我们的最终的强分类器是若干个弱分类器加权平均而得到的。
前向分步学习算法也好理解,我们的算法是通过一轮轮的弱学习器学习,利用前一个弱学习器的结果来更新后一个弱学习器的训练集权重。也就是说,第k-1轮的强学习器为:
而第k轮的强学习器为:
上两式一比较可以得到:
可见强学习器的确是通过前向分步学习算法一步步而得到的。
Adaboost损失函数为指数函数,即定义损失函数为:
利用前向分步学习算法的关系可以得到损失函数为:
假设已经经过了次迭代,已知,令, 依赖于。
将带入损失函数,损失函数转化为:我们继续化简:
并对求导,使其等于0,则就得到了:
其中,即为我们前面的分类误差率。
最后看样本权重的更新。利用和,即可得:
这与我们上面说到的样本权重的更新只差一个规范化因子,两者是等价的。
四 AdaBoost二元分类问题算法流程
这里我们对AdaBoost二元分类问题算法流程做一个总结。
输入为样本集,输出为{-1, +1},弱分类器算法, 弱分类器迭代次数K。
输出为最终的强分类器
1) 初始化样本集权重为:
2) 对于k=1,2,...K:
a) 使用具有权重的样本集来训练数据,得到弱分类器
b)计算的分类误差率:
c) 计算弱分类器的系数:
d) 更新样本集的权重分布:
这里是规范化因子:
3) 构建最终分类器为:
对于Adaboost多元分类算法,其实原理和二元分类类似,最主要区别在弱分类器的系数上。比如Adaboost SAMME算法,它的弱分类器的系数:
其中R为类别数。从上式可以看出,如果是二元分类,R=2,则上式和我们的二元分类算法中的弱分类器的系数一致。
五 Adaboost回归问题的算法流程
这里我们对AdaBoost回归问题算法流程做一个总结。AdaBoost回归算法变种很多,下面的算法为Adaboost R2回归算法过程。
输入为样本集,,弱学习器算法, 弱学习器迭代次数K。
输出为最终的强学习器
1) 初始化样本集权重为:
2) 对于k=1,2,...K:
a) 使用具有权重的样本集来训练数据,得到弱学习器
b) 计算训练集上的最大误差:
c) 计算每个样本的相对误差:
如果是线性误差,则;
如果是平方误差,则
如果是指数误差,则
d) 计算回归误差率:
e) 计算弱学习器的系数:
f) 更新样本集的权重分布为:
这里是规范化因子:
3) 构建最终强学习器为:
其中,是所有的中位数。
六 Adaboost算法的正则化
为了防止Adaboost过拟合,我们通常也会加入正则化项,这个正则化项我们通常称为步长(learning rate)。定义为,对于前面的弱学习器的迭代:
如果我们加上了正则化项,则有:
的取值范围为。对于同样的训练集学习效果,较小的意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。
七 Adaboost的例子
给定如下表所示训练数据,假设弱分类器由或产生,可以看做由一个根节点直接连接两个叶节点的简单决策树,其阈值使该分类器在训练数据集上的分类误差率最低,试用Adaboost算法学习一个强分类器。
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
1 | 1 | 1 | -1 | -1 | -1 | 1 | 1 | 1 | -1 |
解:初始化样本权重系数:
对于=1:
a、在权重为的训练数据上、阈值取2.5时分类误差率最低,故弱分类器为:
b、在训练数据集上的分类误差率
c、计算的系数:
d、更新样本的权重分布:
分类器在训练数据集上有3个误分类点。
对于=2:
a、在权重为的训练数据上、阈值取8.5时分类误差率最低,故弱分类器为:
b、在训练数据集上的分类误差率
c、计算的系数:
d、更新样本的权重分布:
分类器在训练数据集上有3个误分类点。
对于=3:
a、在权重为的训练数据上、阈值取5.5时分类误差率最低,故弱分类器为:
b、在训练数据集上的分类误差率
c、计算的系数:
d、更新样本的权重分布:
分类器在训练数据集上有0个误分类点。
于是最终分类器为:
八 scikit-learn Adaboost类库使用小结
1. Adaboost类库概述
scikit-learn中Adaboost类库比较直接,就是AdaBoostClassifier和AdaBoostRegressor两个,从名字就可以看出AdaBoostClassifier用于分类,AdaBoostRegressor用于回归。
AdaBoostClassifier使用了两种Adaboost分类算法的实现,SAMME和SAMME.R。而AdaBoostRegressor则使用了讲到的Adaboost回归算法的实现,即Adaboost.R2。
当我们对Adaboost调参时,主要要对两部分内容进行调参,第一部分是对我们的Adaboost的框架进行调参, 第二部分是对我们选择的弱分类器进行调参。两者相辅相成。下面就对Adaboost的两个类:AdaBoostClassifier和AdaBoostRegressor从这两部分做一个介绍。
2. AdaBoostClassifier和AdaBoostRegressor框架参数
我们首先来看看AdaBoostClassifier和AdaBoostRegressor框架参数。两者大部分框架参数相同,下面我们一起讨论这些参数,两个类如果有不同点我们会指出。
1)base_estimator:AdaBoostClassifier和AdaBoostRegressor都有,即我们的弱分类学习器或者弱回归学习器。理论上可以选择任何一个分类或者回归学习器,不过需要支持样本权重。我们常用的一般是CART决策树或者神经网络MLP。默认是决策树,即AdaBoostClassifier默认使用CART分类树DecisionTreeClassifier,而AdaBoostRegressor默认使用CART回归树DecisionTreeRegressor。另外有一个要注意的点是,如果我们选择的AdaBoostClassifier算法是SAMME.R,则我们的弱分类学习器还需要支持概率预测,也就是在scikit-learn中弱分类学习器对应的预测方法除了predict还需要有predict_proba。
2)algorithm:这个参数只有AdaBoostClassifier有。主要原因是scikit-learn实现了两种Adaboost分类算法,SAMME和SAMME.R。两者的主要区别是弱学习器权重的度量,SAMME使用了和我们的原理篇里二元分类Adaboost算法的扩展,即用对样本集分类效果作为弱学习器权重,而SAMME.R使用了对样本集分类的预测概率大小来作为弱学习器权重。由于SAMME.R使用了概率度量的连续值,迭代一般比SAMME快,因此AdaBoostClassifier的默认算法algorithm的值也是SAMME.R。我们一般使用默认的SAMME.R就够了,但是要注意的是使用了SAMME.R, 则弱分类学习器参数base_estimator必须限制使用支持概率预测的分类器。SAMME算法则没有这个限制。
3)loss:这个参数只有AdaBoostRegressor有,Adaboost.R2算法需要用到。有线性‘linear’, 平方‘square’和指数 ‘exponential’三种选择, 默认是线性,一般使用线性就足够了,除非你怀疑这个参数导致拟合程度不好。这个值的意义在原理中我们也讲到了,它对应了我们对第k个弱分类器的中第i个样本的误差的处理,即:如果是线性误差,则;如果是平方误差,则,如果是指数误差,则,为训练集上的最大误差
4) n_estimators: AdaBoostClassifier和AdaBoostRegressor都有,就是我们的弱学习器的最大迭代次数,或者说最大的弱学习器的个数。一般来说n_estimators太小,容易欠拟合,n_estimators太大,又容易过拟合,一般选择一个适中的数值。默认是50。在实际调参的过程中,我们常常将n_estimators和下面介绍的参数learning_rate一起考虑。
5) learning_rate: AdaBoostClassifier和AdaBoostRegressor都有,即每个弱学习器的权重缩减系数,在原理中的正则化小节我们也讲到了,加上了正则化项,我们的强学习器的迭代公式为。的取值范围为。对于同样的训练集拟合效果,较小的意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。所以这两个参数n_estimators和learning_rate要一起调参。一般来说,可以从一个小一点的开始调参,默认是1。
3. AdaBoostClassifier和AdaBoostRegressor弱学习器参数
亲爱的读者和支持者们,自动博客加入了打赏功能,陆陆续续收到了各位老铁的打赏。在此,我想由衷地感谢每一位对我们博客的支持和打赏。你们的慷慨与支持,是我们前行的动力与源泉。
日期 | 姓名 | 金额 |
---|---|---|
2023-09-06 | *源 | 19 |
2023-09-11 | *朝科 | 88 |
2023-09-21 | *号 | 5 |
2023-09-16 | *真 | 60 |
2023-10-26 | *通 | 9.9 |
2023-11-04 | *慎 | 0.66 |
2023-11-24 | *恩 | 0.01 |
2023-12-30 | I*B | 1 |
2024-01-28 | *兴 | 20 |
2024-02-01 | QYing | 20 |
2024-02-11 | *督 | 6 |
2024-02-18 | 一*x | 1 |
2024-02-20 | c*l | 18.88 |
2024-01-01 | *I | 5 |
2024-04-08 | *程 | 150 |
2024-04-18 | *超 | 20 |
2024-04-26 | .*V | 30 |
2024-05-08 | D*W | 5 |
2024-05-29 | *辉 | 20 |
2024-05-30 | *雄 | 10 |
2024-06-08 | *: | 10 |
2024-06-23 | 小狮子 | 666 |
2024-06-28 | *s | 6.66 |
2024-06-29 | *炼 | 1 |
2024-06-30 | *! | 1 |
2024-07-08 | *方 | 20 |
2024-07-18 | A*1 | 6.66 |
2024-07-31 | *北 | 12 |
2024-08-13 | *基 | 1 |
2024-08-23 | n*s | 2 |
2024-09-02 | *源 | 50 |
2024-09-04 | *J | 2 |
2024-09-06 | *强 | 8.8 |
2024-09-09 | *波 | 1 |
2024-09-10 | *口 | 1 |
2024-09-10 | *波 | 1 |
2024-09-12 | *波 | 10 |
2024-09-18 | *明 | 1.68 |
2024-09-26 | B*h | 10 |
2024-09-30 | 岁 | 10 |
2024-10-02 | M*i | 1 |
2024-10-14 | *朋 | 10 |
2024-10-22 | *海 | 10 |
2024-10-23 | *南 | 10 |
2024-10-26 | *节 | 6.66 |
2024-10-27 | *o | 5 |
2024-10-28 | W*F | 6.66 |
2024-10-29 | R*n | 6.66 |
2024-11-02 | *球 | 6 |
2024-11-021 | *鑫 | 6.66 |
2024-11-25 | *沙 | 5 |
2024-11-29 | C*n | 2.88 |

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了