1 AdaBoost的基本参数与损失函数
1.1 (理论)AdaBoost基本原理、代码
📖 Adaboost原理
- 在全样本上建立一棵决策树;
- 根据该决策树预测的结果和损失函数值,增加被预测错误的样本在数据集中的样本权重;
- 让加权后的数据集被用于训练下一棵决策树;
- 当全部弱评估器都被建立后,集成算法的输出𝐻(𝑥)等于所有弱评估器输出值的加权平均,加权所用的权重也是在建树过程中被自适应地计算出来的。
这个过程加重“难以被分类正确的样本”的权重,同时降低“容易被分类正确的样本”的权重,而将后续要建立的弱评估器的注意力引导到难以被分类正确的样本上。
🔣 AdaBoost两种类的代码:分类和回归
- 模型特点:没有太多的调参空间
- class sklearn.ensemble.AdaBoostClassifier(base_estimator=None, *, n_estimators=50, learning_rate=1.0, algorithm=‘SAMME.R’, random_state=None)
- class sklearn.ensemble.AdaBoostRegressor(base_estimator=None, *, n_estimators=50, learning_rate=1.0, loss=‘linear’, random_state=None)
1.2 🔣 AdaBoost参数
参数 | 参数含义 |
---|---|
base_estimator | 弱评估器 |
n_estimators | 集成算法中弱评估器的数量 |
learning_rate | 迭代中所使用的学习率 |
algorithm(分类器专属) | 用于指定分类ADB中使用的具体实现方法 |
loss(回归器专属) | 用于指定回归ADB中使用的损失函数 |
random_state | 用于控制每次建树之前随机抽样过程的随机数种子 |
🤷♀️1.2.1 base_estimator的使用_案例:手写数字数据集_python
📖 base_estimator简介
- 对比Bagging对弱评估器偏差小,方差大的偏好,AdaBoost可以使用任意弱评估器,默认为决策树;
- 在sklearn中,ADB分类器的默认弱评估器是最大深度为1的“树桩”;ADB回归器的默认评估器是最大深度为3的“树苗”;
- 建模完成后,可以使用base_estimator_来查看当前弱评估器;可以使用estimators_查看当前集成模型中所有弱评估器的情况
🗣 案例:base_estimator设定与属性查看
from sklearn.ensemble import AdaBoostClassifier as ABC
from sklearn.ensemble import AdaBoostRegressor as ABR
model_c=ABC(n_estimators=3).fit(X_c,y_c)
model_r=ABR(n_estimators=3).fit(X_g,y_g)
model_c.base_estimator_
model_r.base_estimator_
model_c.estimators_
model_r.estimators_
🗣 自建弱评估器
from sklearn.tree import DecisionTreeClassifier as DTC
base_estimator=DTC(max_depth=10,max_features=30,random_state=7)
model=ABC(base_estimator=base_estimator
,n_estimators=3).fit(X_c,y_c)
model.base_estimator_
model.estimators_
📖 注意:为了保证集成算法中的树不一致,AdaBoost会默认消除我们填写在弱评估器中的random_state。
1.2.2 learning_rate
📖 学习率的特点
- 学习率参数控制Boosting集成过程中 H ( x i ) H(x_i) H(xi)的增长速度;
- 评估器数量与学习率的关系:当学习率很大时, H ( x i ) H(x_i) H(xi)增长得更快,我们所需的n_estimators更少,当学习率较小时, H ( x i ) H(x_i) H(xi)增长较慢,我们所需的n_estimators就更多,因此boosting算法往往会需要在n_estimators与learning_rate当中做出权衡
📌 学习率
Boosting集成算法输出公式如下:
H ( x i ) = ∑ t = 1 T ϕ t f t ( x i ) H(x_i) = \displaystyle \sum_{t=1}^T\phi_tf_t(x_i) H(xi)=t=1∑Tϕtft(xi)
其中, ϕ t \phi_t ϕt为第t棵树的权重。对于第 t t t次迭代来说,则有:
H t ( x i ) = H t − 1 ( x i ) + ϕ t f t ( x i ) H_t(x_i) = H_{t-1}(x_i) + \phi_tf_t(x_i) Ht(xi)=Ht−1(xi)+ϕtft(xi)
在这个一般过程中,每次将本轮建好的决策树加入之前的建树结果时,可以在权重 ϕ \phi ϕ前面增加参数 η \color{red}\eta η,表示为第t棵树加入整体集成算法时的学习率,对标参数learning_rate。
H t ( x i ) = H t − 1 ( x i ) + η ϕ t f t ( x i ) H_t(x_i) = H_{t-1}(x_i) + \boldsymbol{\color{red}\eta} \phi_tf_t(x_i) Ht(xi)=Ht−1(xi)+ηϕtft(xi)
1.2.3 algorithm与loss
📖 algorithm特点
- 备选项有"SAMME"与"SAMME.R"两个字符串,代表了两种不同的、实现AdaBoost分类的手段:AdaBoost-SAMME与AdaBoost-SAMME.R。
- SAMME是基于算法输出的具体分类结果(例如-1,1,2)进行计算,
- SAMME.R则是在SAMME基础上改进过后、基于弱分配器输出的概率值进行计算。
- 两种方法都支持在AdaBoost上完成多分类任务,但SAMME.R往往能够得到更好的结果,因此sklearn中的默认值是SAMME.R,因此sklearn中默认可以输入的base_estimators也需要是能够输出预测概率的弱评估器。
- 实际在预测时,AdaBoost输出的𝐻(𝑥)也针对于某一类别的概率。
- 不被允许选择算法所使用的损失函数,这是因为SAMME与SAMME.R使用了相同的损失函数:二分类指数损失(Exponential Loss Function)与多分类指数损失(Multi-class Exponential loss function)。
📌 二分类指数损失
L ( H ( x ) , y ) = e − y H ∗ ( x ) L(H(x),y) = e^{-yH^*(x)} L(H(x),y)=e−yH∗(x)
其中 y y y为真实分类, H ( x ) H^(x) H(x)*则是从集成算法输出的概率结果 H ( x ) H(x) H(x)转换来的向量。
转换规则如下:
H ∗ ( x ) = { 1 i f H ( x ) > 0.5 − 1 i f H ( x ) < 0.5 H^*(x)= \begin{cases} 1& if \ H(x)>0.5 \\ -1& if\ H(x) < 0.5 \end{cases} H∗(x)={1−1if H(x)>0.5if H(x)<0.5
- 在sklearn当中,由于 H ( x ) H(x) H(x)是概率值,因此需要转换为 H ∗ ( x ) H^*(x) H∗(x),如果在其他实现AdaBoost的算法库中, H ( x ) H(x) H(x)输出直接为预测类别,则可以不执行转换流程。
- 根据指数损失的特殊性质,二分类状况下的类别取值只能为-1或1,因此
y
y
y的取值只能为-1或1。
- 当算法预测正确时, y H ∗ ( x ) yH^*(x) yH∗(x)的符号为正,则在函数 e − x e^{-x} e−x上损失很小。
- 当算法预测错误时, y H ∗ ( x ) yH^*(x) yH∗(x)的符号为负,则在函数 e − x e^{-x} e−x上损失较大。
- 通过二分类损失,可以保证损失函数的结果正确时,输出的值在[0,1]之间。
📌 多分类指数损失
L ( H ( x ) , y ) = e x p ( − 1 K y ∗ ⋅ H ∗ ( x ) ) = e x p ( − 1 K ( y ∗ 1 H ∗ 1 ( x ) + y ∗ 2 H ∗ 2 ( x ) + . . . + y ∗ k H ∗ k ( x ) ) ) \begin{aligned} L(H(x),y) &=exp \left( -\frac{1}{K}\boldsymbol{y^* · H^*(x)} \right) \\ & = exp \left( -\frac{1}{K}(y^{*1}H^{*1}(x)+y^{*2}H^{*2}(x) \ + \ ... + y^{*k}H^{*k}(x)) \right)\end{aligned} L(H(x),y)=exp(−K1y∗⋅H∗(x))=exp(−K1(y∗1H∗1(x)+y∗2H∗2(x) + ...+y∗kH∗k(x)))
其中, K K K为总类别数,如四分类时, K = 4 K=4 K=4; y ∗ \boldsymbol{y^*} y∗ ∗ H ∗ ( x ) *\boldsymbol{H^*(x)} ∗H∗(x)是*多分类具体情况、以及集成算法实际输出 H ( x ) H(x) H(x)转化出的向量,其中 y ∗ 1 y^{*1} y∗1与 H ∗ 1 ( x ) H^{*1}(x) H∗1(x)的上标1都表示当前类别。
根据概率转换公式,可得:
H ∗ ( x ) = { 1 i f k = a r g m a x H ( x ) − 1 K − 1 i f k ≠ a r g m a x H ( x ) H^*(x)= \begin{cases} 1& if \ k = argmaxH(x) \\ -\frac{1}{K-1}& if\ k \neq argmaxH(x) \end{cases} H∗(x)={1−K−11if k=argmaxH(x)if k=argmaxH(x)
在softmax函数中,当预测值或真实值不等于 k k k时,赋予的向量值为0,而不是 − 1 K − 1 -\frac{1}{K-1} −K−11。
📌 loss
-
参数可选三种损失函数,分别是"linear"(线性),“square”(平方),“exponential”(指数)
-
R2算法线性损失——
L i = ∣ H ( x i ) − y i ∣ D L_i = \frac{|H(x_i) - y_i|}{D} Li=D∣H(xi)−yi∣
-
R2算法平方损失——
L i = ∣ H ( x i ) − y i ∣ 2 D 2 L_i = \frac{|H(x_i) - y_i|^2}{D^2} Li=D2∣H(xi)−yi∣2
-
R2算法指数损失——
L i = 1 − e x p ( − ∣ H ( x i ) − y i ∣ D ) L_i = 1 - exp \left( \frac{-|H(x_i) - y_i|}{D} \right) Li=1−exp(D−∣H(xi)−yi∣)
-
-
其中 D = s u p ∣ H ( x i ) − y i ∣ , i = 1 , 2 , . . . , N D = sup|H(x_i) - y_i|, i = 1,2,...,N D=sup∣H(xi)−yi∣,i=1,2,...,N,为1~N号样本中真实值与预测值差距最大的那一组差异。
-
y i y_i yi 为真实标签, H ( x i ) H(x_i) H(xi) 为预测标签,sup表示“取最大值”(数学中,max需要元素固定的数值,sup中的元素可以是表达式)。
-
由于损失的分母限定为最大差异D,所以损失必然为小于1的数,用这个限定来方便整个AdaBoost算法求解。
2 Adaboost回归的求解流程_数学原理
☑️ Boosting算法原理的相关基础问题
- 损失函数 𝐿(𝑥,𝑦) 的表达式是什么?损失函数如何影响模型构建?
- 弱评估器 𝑓(𝑥) 是什么,当下boosting算法使用的具体建树过程是什么?
- 综合集成结果 𝐻(𝑥) 是什么?集成算法具体如何输出集成结果?
- 是加权求和吗?如果是,加权求和中的权重如何求解?
- 训练过程中,拟合的数据 𝑋 与 𝑦 分别是什么?
- 模型训练到什么时候停下来最好?
2.1 AdaBoost.R2回归算法的流程
📖 AdaBoost.R2特点
- 是当前AdaBoost实现流程中使用最多的回归类实践方式;
- 囊括了对数据进行有放回抽样、按损失函数结果调整样本权重、自动计算弱分类器权重、并输出预测结果等AdaBoost算法经典的全流程;
- 在AdaBoost回归方法当中,损失函数并没有明显的被“最小化”的过程,我们借助损失函数来自然地调整数据的权重,从而在迭代中不断减小整体损失;但在AdaBoost分类方法当中,有针对损失函数求解一阶导数、并让一阶导数为0的过程,该过程影响AdaBoost分类过程中求解弱分类器权重的内容,同时也影响AdaBoost分类过程中对于样本权重的迭代更新。
- 可以参阅论文《Multi-class AdaBoost》以及sklearn源码:https://github.com/scikit-learn/scikit-learn/blob/0d378913b/sklearn/ensemble/_weight_boosting.py#L913
2.2 🔑 AdaBoost.R2流程
假设现有数据集N,含有样本 𝑀 个,任意样本编号为 𝑖 ,同时,弱评估器为决策树 𝑓 ,总共学习 𝑇 轮,则AdaBoost.R2的基本流程如下所示:
- 初始化原始数据集的权重 w i w_i wi ,其中任意 w i = 1 M w_i=\frac{1}{M} wi=M1
-
在现有数据集 𝑁 中,有放回抽样 𝑀 个样本,构成训练集 N t N^t Nt 。在每次抽取一个样本时,任意样本被抽中的概率为 P i t = w i ∑ w i P^t_i=\frac{w_i}{∑w_i} Pit=∑wiwi ,很显然,该概率就是当前样本在训练集 N t N^t Nt 中的权重。当从初始权重中抽样时,概率 P i 1 = 1 M P_i^1 = \frac{1}{M} Pi1=M1 ,当后续权重变化时,拥有更大权重的样本被抽中的概率会更大。
-
在训练集 N t N^t Nt上按照CART树规则建立一棵回归树 f t f^t ft,训练时所拟合的标签为样本的真实标签 y i t y^t_i yit。
-
将 N t N^t Nt上所有的样本输入 f t f^t ft进行预测,得出预测结果 f t ( x i ) f^t(x_i) ft(xi),其中i = 1,2,…M
-
计算单一样本 i i i上的损失函数 L i t = L ( f t ( x i ) , y i ) L^t_i = L(f^t(x_i),y_i) Lit=L(ft(xi),yi)
-
计算全样本上的加权平均损失 L t ˉ = ∑ i = 1 M L i t P i t \bar{L^t} = \sum_{i=1}^ML_i^tP_i^t Ltˉ=∑i=1MLitPit
-
依据加权平均损失 L t ˉ \bar{L^t} Ltˉ计算衡量当前集成算法的置信度 β t = L t ˉ 1 − L t ˉ + λ \beta^t = \frac{\bar{L^t}}{1-\bar{L^t} + \lambda} βt=1−Ltˉ+λLtˉ
加权平均损失 L t ˉ \bar{L^t} Ltˉ越小, β t \beta^t βt越小,模型效果越好。 -
依据置信度评估 β t \beta_t βt更新样本权重, w i = w i β ( 1 − L i ) w_i = w_i\beta^{(1-L_i)} wi=wiβ(1−Li)
-
求解迭代过程中弱分类器 f t f^t ft所需的权重, ϕ t = l o g ( 1 β t ) \phi^t = log(\frac{1}{\beta^t}) ϕt=log(βt1)
-
求解出当前迭代 t t t下集成算法的输出值:
H t ( x i ) = H t − 1 ( x i ) + η ϕ t f t ( x i ) H^t(x_i) = H^{t-1}(x_i) + \eta \phi^t f^t(x_i) Ht(xi)=Ht−1(xi)+ηϕtft(xi)
📖 AdaBoost的停止条件
( ∑ t : H t ( x ) ≤ y l o g 1 β t ) ≥ ( 1 2 ∑ t = 1 T l o g 1 β t ) \left(\sum_{t:H^t(x) \leq y} log\frac{1}{\beta^t} \right)\ \ \geq \ \ \left(\frac{1}{2}\sum_{t=1}^T log\frac{1}{\beta^t} \right) ⎝⎛t:Ht(x)≤y∑logβt1⎠⎞ ≥ (21t=1∑Tlogβt1)
当上式相等时, H t ( x ) H^t(x) Ht(x)停止迭代计算。