1 概述
-
定义:Adaboost ,“Adaptive Boosting”(自适应增强),是一种迭代算法,其核心思想是针对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器)。由Yoav Freund和Robert Schapire于1995年提出。
-
思想
前面的模型对训练集预测后,在每个样本上都会产生一个不同损失,AdaBoost会为每个样本更新权重,分类错误的样本要提高权重,分类正确的样本要降低权重,下一个学习器会更加**“关注”权重大的样本;每一次得到一个模型后,根据模型在该轮数据上的表现给当前模型设置一个权重**,表现好的权重大,最终带权叠加得到最终集成模型。
2 分类算法流程
-
输入:训练集为 T={(x1,y1),(x2,y2),...,(xN,yN)},y∈{−1,+1}T=\{ (x_1,y_1),(x_2,y_2),...,(x_N,y_N) \},y∈\{−1,+1\}T={(x1,y1),(x2,y2),...,(xN,yN)},y∈{−1,+1},训练弱学习器
M
个。 -
输出:最终的强学习器
G(x)
-
初始化样本集权重为 D1=(w11,w12,...,w1N)D_1=(w_{11},w_{12},...,w_{1N} )D1=(w11,w12,...,w1N),其中 w1i=1N,i=1,2,...,Nw_{1i}=\frac{1}{N} ,i=1,2,...,Nw1i=N1,i=1,2,...,N
-
对每个弱学习器 Gm(x),m=1,2,...,MG_m(x),m=1,2,...,MGm(x),m=1,2,...,M
a) 使用具有权值分布DmD_mDm的训练数据来训练模型,得到弱学习器Gm(x)G_m(x)Gm(x)
b) 定义第 mmm 个弱分类器Gm(x)G_m(x)Gm(x)在训练集上的误差率 eme_mem
em=∑i=1NP(Gm(xi)≠yi)=∑i=1NwmiI(Gm(xi)≠yi) e_m=\sum_{i=1}^NP(G_m (x_i)≠y_i)=\sum_{i=1}^Nw_{mi} I(G_m (x_i)≠y_i) em=i=1∑NP(Gm(xi)=yi)=i=1∑NwmiI(Gm(xi)=yi)
c) 计算弱学习器的系数
αm=12ln1−emem \alpha_m=\frac{1}{2} \ln \frac{1−e_m}{e_m } αm=21lnem1−em
d) 更新训练集中样本的权重分布,使Dm+1D_{m+1}Dm+1成为一个概率分布,ZmZ_mZm是规范化因子。
Dm+1=(wm+1,1,...,wm+1,i,...,wm+1,N)Zm=∑i=1Nwm,iexp(−αmyiGm(xi))wm+1,i=wm,iZmexp(−αmyiGm(xi)),i=1,2,3,…,N D_{m+1}=(w_{m+1,1},...,w_{m+1,i,...,w_{m+1,N}})\\ Z_m=\sum_{i=1}^Nw_{m,i} \exp(−\alpha_m y_i G_m (x_i ))\\ w_{m+1,i}=\frac{w_{m,i}}{Z_m} \exp(−\alpha_m y_i G_m (x_i )),i = 1, 2, 3,…,N\\ Dm+1=(wm+1,1,...,wm+1,i,...,wm+1,N)Zm=i=1∑Nwm,iexp(−αmyiGm(xi))wm+1,i=Zmwm,iexp(−αmyiGm(xi)),i=1,2,3,…,N -
最终学习器为:
H(x)=sign(∑m=1MαmGm(x))sign(x)={−1,x<00,x=01,x>0
H(x)=sign(\sum_{m=1}^M \alpha_m G_m (x)) \\
sign(x)=\left\{
\begin{aligned}
-1,x<0\\
0,x=0\\
1,x>0
\end{aligned}
\right.
H(x)=sign(m=1∑MαmGm(x))sign(x)=⎩⎨⎧−1,x<00,x=01,x>0
这里Adaboost算法中引入了正则化,通过一个称为学习率的参数vvv对弱分类器的权重大小进行控制,即
Hm(x)=Hm−1(x)+vαmGm(x)
H_m(x)=H_{m-1}(x)+v\alpha_mG_m(x)
Hm(x)=Hm−1(x)+vαmGm(x)
第一次设置样本权重相同,通过错误率计算学习器权重,更新下一次样本权重。计算每个学习器权重和结果的乘积,计算最终结果。
3 分类案例详解
有如下的训练样本,我们需要构建强分类器对其进行分类。x是特征,y是标签
x | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
y | 1 | 1 | 1 | -1 | -1 | -1 | 1 | 1 | 1 | -1 |
1)设置初始的样本权重值1/N1/N1/N
初始每个样本的权重为w1,i=0.1,i=1,2,⋯,10w_{1,i}=0.1 , i=1,2,⋯,10w1,i=0.1,i=1,2,⋯,10
2)对于m=1,2,...,Mm=1,2,...,Mm=1,2,...,M:
初始第1个弱分类器,经过决策树分类原则,知道最佳阈值点为2,得到弱分类器:
G1(x)={1,x≤2−1,x>2
G_1 (x)=
\left\{
\begin{aligned}
1,x≤2\\
−1,x>2
\end{aligned}
\right.
G1(x)={1,x≤2−1,x>2
通过误差率计算,可以计算出误差率为
e1=∑i=1Nw1iI(G1(x)≠yi)=0.3
e_1=\sum_{i=1}^Nw_{1i} I(G_1 (x)≠y_i) =0.3
e1=i=1∑Nw1iI(G1(x)=yi)=0.3
计算G1(x)G_1 (x)G1(x)在强分类器中的权重系数
α1=12log1−e1e1=0.4236
\alpha_1=\frac{1}{2} \log \frac{1−e_1}{e_1 }=0.4236
α1=21loge11−e1=0.4236
更新样本的权重分布,用于下一轮迭代:
Z1=∑i=1N(w1,iexp(−α1yiG1(xi)))w2,i=w1,iz1exp(−α2yiG2(xi)),i=1,2,3,…
Z_1=\sum_{i=1}^N (w_{1,i} \exp(−\alpha_1 y_i G_1 (x_i )))\\
w_{2,i}=\frac{w_{1,i}}{z_1} \exp(−\alpha_2 y_i G_2 (x_i )),i = 1, 2, 3,…
Z1=i=1∑N(w1,iexp(−α1yiG1(xi)))w2,i=z1w1,iexp(−α2yiG2(xi)),i=1,2,3,…
更新后的权重进行调整
w2=(0.0715,0.0715,0.0715,0.0715,0.0715,0.0715,0.1666,0.1666,0.1666,0.0715)
w_2=(0.0715,0.0715,0.0715,0.0715,0.0715,0.0715,0.1666,0.1666,0.1666,0.0715)
w2=(0.0715,0.0715,0.0715,0.0715,0.0715,0.0715,0.1666,0.1666,0.1666,0.0715)
得到第一轮迭代的强分类器
sign(F1(x))=sign(0.4236G1(x))
sign(F_1(x))=sign(0.4236G_1(x))
sign(F1(x))=sign(0.4236G1(x))
依此类推,经过多轮以后,得到如下强分类器:
sign(F3(x))=sign(0.4236G1(x)+0.6496G2(x)+0.7514G3(x))
sign(F_3(x))=sign(0.4236G_1(x)+0.6496G_2(x)+0.7514G_3(x))
sign(F3(x))=sign(0.4236G1(x)+0.6496G2(x)+0.7514G3(x))
分类误差率为0,结束迭代。
F(x)=sign(F3(x))F(x)=sign(F_3(x))F(x)=sign(F3(x))就是最终的强分类器。
4 回归算法流程
输入:训练集为T=(x1,y1),(x2,y2),...,(xN,yN),y∈RT={(x_1,y_1),(x_2,y_2),...,(x_N,y_N)},y∈RT=(x1,y1),(x2,y2),...,(xN,yN),y∈R,训练弱学习器MMM个。
输出:最终的强学习器G(x)G (x)G(x)
- 初始化训练集权重为
D1=(w11,w12,...,w1N),w1i=1N,i=1,2,...,N D_1=(w_{11},w_{12},...,w_{1N} ),w_{1i}=\frac{1}{N}, i=1,2,...,N D1=(w11,w12,...,w1N),w1i=N1,i=1,2,...,N
-
对于m=1,2,...,Mm=1,2,...,Mm=1,2,...,M:
a) 使用具有权值分布DmD_mDm的训练数据来训练模型,得到弱学习器Gm(x)G_m(x)Gm(x)
b) 计算Gm(x)G_m(x)Gm(x)的在训练集T上的最大误差EmE_mEm和回归误差率eme_mem
Em=max∣yi−Gm(xi)∣,i=1,2,...,Nem=∑i=1Nwmi(yi−Gm(xi))2Em2 E_m=\max|y_i-G_m(x_i)|,i=1,2,...,N\\ e_m=\sum_{i=1}^Nw_{mi} \frac{(y_i−G_m(x_i) )^2}{E_m^2 } Em=max∣yi−Gm(xi)∣,i=1,2,...,Nem=i=1∑NwmiEm2(yi−Gm(xi))2
c) 计算αmα_mαm(用于计算弱学习器的系数)
αm=em1−em α_m=\frac{e_m}{1−e_m } αm=1−emem
d) 更新训练集中样本的权重
Zm=∑i=1Nwm,iexp(−αmyiGm(xi))wm+1,i=∑i=1Nwm,iZmαm1−em Z_m=\sum_{i=1}^{N} w_{m,i} \exp(−\alpha_m y_i G_m (x_i ))\\ w_{m+1,i}=\sum_{i=1}^{N} \frac{w_{m,i}}{Z_m} \alpha_m^{1-e_m} Zm=i=1∑Nwm,iexp(−αmyiGm(xi))wm+1,i=i=1∑NZmwm,iαm1−em
-
最终学习器
先对弱学习器进行加权,取中位数,再组成最终模型
G(x)=[∑m=1M(ln1αm)]g(x),其中g(x)是所有αmGm(x)的中位数,m=1,2,...,M G(x)=[\sum_{m=1}^M (ln\frac{1}{\alpha_m})] g(x),其中g(x)是所有\alpha_m G_m (x)的中位数,m=1,2,...,M G(x)=[m=1∑M(lnαm1)]g(x),其中g(x)是所有αmGm(x)的中位数,m=1,2,...,M
5 AdaBoost函数模型
5.1 AdaBoostingClassifier
class sklearn.ensemble. AdaBoostClassifier(base_estimator=None,*, n_estimators=50,learning_rate=1.0,algorithm='SAMME.R', random_state=None)
-
参数
-
base_estimator
: 对象类型,默认值为None
该参数设置为None时,使用默认基学习器DecisionTreeClassifier(max_depth=1),即默认使用深度为1的CART树。 -
algorithm
:
可选参数,默认为SAMME.R。scikit-learn实现了两种Adaboost分类算法:SAMME和SAMME.R。两者的主要区别在于基学习器权重的度量方法:- SAMME使用对数据集的分类效果作为基学习器的权重(上述流程是二分类,此算法为多分类,改变权重系数计算αm,αm=12ln(1−emem)+ln(∣Y∣−1)\alpha_m,\alpha_m=\frac{1}{2}\ln(\frac{1-e_m}{e_m})+\ln(|Y|-1)αm,αm=21ln(em1−em)+ln(∣Y∣−1),∣Y∣|Y|∣Y∣是分类数,加ln(∣Y∣−1)\ln(|Y|-1)ln(∣Y∣−1)可以增大使αm\alpha_mαm为0时的eme_mem);
- SAMME.R使用对数据集分类的预测概率大小来作为基学习器的权重。
由于SAMME.R使用了概率度量的连续值,迭代速度一般比SAMME快,因此
AdaBoostClassifier
的algorithm参数默认值也设置为SAMME.R。注意:若使用的是SAMME.R算法,则base_estimator参数必须限制使用支持概率预测的分类器,SAMME算法则没有这个限制。 -
n_estimators
: 整型,默认值为50
基学习器的最大迭代次数(即最大的基学习器个数)。AdaBoost的分类效果对n_estimators
取值的敏感性较高:n_estimator
太小,基学习器数量太少,容易造成欠拟合;n_estimators
太大,基学习器数量太多,容易造成过拟合;
所以,在实际使用中,
n_estimators
的值不宜过大,也不能太小,需要通过调参找到一个合适的取值。在实际调参的过程中,常常将n_estimators
和下面要介绍到的参数learning_rate
一起考虑。 -
learning_rate
: 浮点型,默认为1.0
表示每个基学习器的权重缩减系数(公式中的αm\alpha_mαm)。该参数对AdaBoost分类效果的影响也很大,所以在实际使用中,需要通过调参,在n_estimators
和learning_rate
这两个参数之间找到平衡。在实例2中将会对这一过程做详细的探索。 -
random_state
: 整型,默认为None
为每个基学习器设置相同的随机数种子,确保多次运行所生成的随机数状态均一致,便于调参与观察。
-
-
属性
AdaBoostingClassifier类有很多属性,如下:base_estimator_
:返回基学习器(包括种类、详细参数等信息)。estimators_
:返回对数据集进行拟合之后的所有基学习器所组成的列表。classes_
:返回所有类别的标签。n_class
:返回总类别数。estimator_weights_
:返回每个基学习器所对应权重所组成的列表。estimator_errors_
:返回每个基学习器的分类错误率所组成的列表。
-
常用方法
AdaBoostingClassifier类有很多方法,常用的方法如下:decision_function(X)
:得到分类器对数据集XXX中各个样本的计算结果,分为如下两种情况:- 若数据集只有两个类别,则返回的计算结果的尺寸为 shape=(样本数,1)shape=(样本数,1)shape=(样本数,1);
- 若数据集有k(k>2)k(k>2)k(k>2)个类别,则返回的计算结果的尺寸为shape=(样本数,k)shape=(样本数,k)shape=(样本数,k)。
以二分类为例,假设AdaBoost分类器abt对样本xxx的计算结果
abt.decision_functiuon(x)=[-0.009] ,由于-0.009到0的距离比到1的距离更近,所以分类器预测xxx属于类别0;
假设abt对样本xxx的计算结果 abt.decision_functiuon(x)=[0.999] ,由于0.999到1的距离比到0的距离更近,所以分类器预测xxx属于类别1。多分类任务也同理。fit(X,y,[,sample_weight]
:拟合数据集。get_params([deep])
:deepdeepdeep参数指定为TrueTrueTrue 时,返回集成分类器的各项参数值。predict(X)
:对样本进行预测。predict_proba(X)
:计算出样本XXX属于各个类别的概率。predict_log_proba(X)
:预测结果以概率值的自然对数值返回。
( 这里简单介绍一下上面两种方法的区别。比如在一个二分类任务中,AdaBoost分类器abt对一个样本xxx的预测结果为[[0.8, 0.2]],即 abt.predict_proba(x)= [[0.8,0.2]] ,表示该分类器预测出xxx属于类别0的概率为0.8、属于类别1的概率为0.2;然后再对这两个值分别取自然对数,返回的结果为[[-0.2231, -1.6094]],即 abt.predict_log_proba(x)=[[-0.2231, -1.6094]] )
5.2 AdaBoostRegressor
class sklearn.ensemble.AdaBoostRegressor(base_estimator=None, *, n_estimators=50, learning_rate=1.0, loss='linear', random_state=None)
-
参数
-
base_estimator
: 对象类型,默认值为None
该参数不指定时,使用DecisionTreeRegressor(max_depth=3)作为基学习器,即默认使用深度为3的回归决策树。 -
n_estimators
: 整型,默认值为50 基学习器的最大迭代次数(即最大的基学习器个数)。 -
learning_rate
: 浮点型,默认为1.0 表示每个基学习器的权重缩减系数。 -
loss
:可选项为 {‘linear’, ‘square’, ‘exponential’},默认为‘linear’。
定义误差函数,各个选项的含义如下:‘linear’:线性损失函数, ‘square’:平方损失函数, ‘exponential’:指数损失函数
-
random_state
: 整型,默认为None
为每个基学习器设置相同的随机数种子,确保多次运行所生成的随机数状态均一致,便于调参与观察。
-
-
属性
AdaBoostingRegressor
类的全部属性只有5个,比AdaBoostingClassifier
类少。如下:
base_estimator_
:返回基学习器(包括种类、详细参数等信息)。
estimators_
:返回对数据集进行拟合之后的所有基学习器所组成的列表。
estimator_weights_
:返回每个基学习器所对应权重所组成的列表。
estimator_errors_
:返回每个基学习器的回归损失所组成的列表。
feature_importances_
:返回数据集中每个特征的权重的组成的列表。 -
常用方法
AdaBoostingRegressor
类的常用方法如下:
fit(X,y,[,sample_weight]
:拟合数据集。
get_params([deep])
:deepdeepdeep参数指定为TrueTrueTrue时,返回集成回归器的各项参数值。
predict(X)
:对样本数据集XXX进行回归预测,返回预测出的数值。
staged_predict(X)
:获取对数据集XXX的阶梯测试准确率。
staged_score(X)
:获取对数据集XXX的阶梯训练准确率。
set_params(**params)
:以字典的形式传入参数**params,设置集成学习器的各项参数。
6 Adaboost代码实战
import pandas as pd
import numpy as np
from sklearn.ensemble import AdaBoostClassifier
df = pd.DataFrame([[0,1],[1,1],[2,1],[3,-1],[4,-1],
[5,-1],[6,1],[7,1],[8,1],[9,-1]])
X = df.iloc[:,[0]]
Y = df.iloc[:,-1]
model = AdaBoostClassifier(n_estimators=10,).fit(X,Y)
model.predict(X)
import pandas as pd
import numpy as np
from sklearn.ensemble import AdaBoostRegressor
from sklearn.tree import DecisionTreeRegressor
df = pd.DataFrame([[1,5.56],[2,5.7],[3,5.91],[4,6.4],[5,6.8],
[6,7.05],[7,8.9],[8,8.7111],[9,9.0],[10,9.05]])
X = df.iloc[:,[0]]
Y = df.iloc[:,-1]
model = DecisionTreeRegressor(max_depth=3)
model = AdaBoostRegressor(n_estimators=5,base_estimator=model,learning_rate=0.01).fit(X,Y)
model.predict(X)
7 Adaboost小结
-
优点:
- 可以使用各种回归分类模型来构建弱学习器,非常灵活
- Sklearn中对AdaBoost的实现是从带权学习视角出发的,思想朴素,易于理解
- 控制迭代次数可以一定程度防止发生过拟合
-
缺点:对异常样本敏感,异常样本在迭代中可能会获得较高的权重,影响最终预测准确性。
-
提升树:AdaBoost思想结合决策树的基学习器,就得到提升树模型。提升树做分类时,基学习器选CART分类树;回归时选CART回归树
-
两个视角:带权学习视角、前向分布学习视角
在前向分步学习视角下,当提升树的损失函数是平方损失和指数损失时,优化是简单的,但对一般损失函数而言优化难度大,即没有通用的求解方案
因此2001年,Friedman提出了一个通用方案——梯度提升,起名为GBDT