datawhale 10月学习——树模型与集成学习:AdaBoost

本文深入探讨了AdaBoost算法,包括二分类AdaBoost(SAMME)的详细流程,以及SAMME.R在回归问题中的应用。通过实例展示了AdaBoost如何通过迭代调整样本权重和构建弱分类器,最终形成强分类器的过程。同时,给出了自定义的AdaBoost代码实现,并与sklearn库进行了对比验证。
摘要由CSDN通过智能技术生成

前情回顾

  1. 决策树
  2. CART树的实现
  3. 集成模式
  4. 两种并行集成的树模型

结论速递

本次学习了解了AdaBoost的常见方法:用于分类的SAMME和用于回归的Adaboost.R2,学习内容比较硬核,根据李航《统计学习方法》进行了一定的重新整理。

1 AdaBoost

1.1 概述

对提升方法来说,有两个问题需要回答:一是在每一轮如何改变训练数据的权值或概率分布;二是如何将弱分类器组合成一个强分类器。

关于第一个问题,AdaBoost的做法是,提高那些被前一轮弱分类器错误分类样本的全职,而降低那些被正确分类样本的权值;
对于第二个问题,采取加权多数表决的方法,具体地,加大分类误差率小的弱分类器的权值,使其在表决中起较大的作用,减小分类误差率大的弱分类器的权值,使其在表决中其较小的作用。

1.2 分类损失

AdaBoost所用的分类损失函数如下

对于 K K K分类问题而言,当样本标签 y = [ y 1 , . . . , y K ] T \mathbf{y}=[y_1,...,y_K]^T y=[y1,...,yK]T的类别 S ( y ) S(\mathbf{y}) S(y)为第 k k k类( k = 1 , . . . , K k=1,...,K k=1,...,K)时,标签 y \mathbf{y} y的第 i i i个( i = 1 , . . . , K i=1,...,K i=1,...,K)元素 y i y_i yi满足
y i = { 1 , i f   i = k − 1 K − 1 , i f   i ≠ k y_i=\left\{ \begin{aligned} &1,\quad &{\rm if}\ i=k\\ &-\frac{1}{K-1},\quad &{\rm if}\ i\neq k \end{aligned} \right. yi=1,K11,if i=kif i=k
设模型的输出结果为 f = [ f 1 , . . . , f K ] T \mathbf{f}=[f_1,...,f_K]^T f=[f1,...,fK]T,则记损失函数为
L ( y , f ) = exp ⁡ ( − y T f K ) L(\mathbf{y},\mathbf{f})=\exp(-\frac{\mathbf{y}^T\mathbf{f}}{K}) L(y,f)=exp(KyTf)

【思考题】假设有一个3分类问题,标签类别为第2类,模型输出的类别标签为[-0.1,-0.3,0.4],请计算对应的指数损失。
首先可以写出标签 y = [ − 1 2 , 1 , − 1 2 ] \mathbf{y}=[-\dfrac{1}{2},1,-\dfrac{1}{2}] y=[21,1,21],则损失函数为
L ( y , f ) = exp ⁡ ( − y T f K ) = exp ⁡ ( − [ − 1 2 , 1 , − 1 2 ] T × [ − 0.1 , − 0.3 , 0.4 ] 3 ) = 1.162 \begin{aligned} L(\mathbf{y},\mathbf{f})&=\exp(-\frac{\mathbf{y}^T\mathbf{f}}{K})\\ &=\exp(-\dfrac{[-\dfrac{1}{2},1,-\dfrac{1}{2}]^T×[-0.1,-0.3,0.4]}{3})\\ &=1.162 \end{aligned} L(y,f)=exp(KyTf)=exp(3[21,1,21]T×[0.1,0.3,0.4])=1.162
在这里插入图片描述

2 SAMME

2.1 二分类AdaBoost

假定一个二分类的训练数据集
T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } T = \{ (x_1,y_1), (x_2,y_2), ... ,(x_N,y_N)\} T={(x1,y1),(x2,y2),...,(xN,yN)}
其中 y i ∈ { − 1 , + 1 } y_i \in \{ -1,+1\} yi{1,+1}

则流程如下

  1. 初始化训练数据的权值分布
    D 1 = ( w 11 , . . . , w 1 i , . . . , w 1 N ) , w 1 i = 1 N , i = 1 , 2 , . . . , N D_1 = (w_{11},...,w_{1i},...,w_{1N}), w_{1i} = \dfrac{1}{N}, i=1,2,...,N D1=(w11,...,w1i,...,w1N),w1i=N1,i=1,2,...,N
  2. m = 1 , 2 , . . . , M m=1,2,...,M m=1,2,...,M
    1. 使用具有权值分布 D m D_m Dm的训练数据集学习,得到基本分类器
      G m ( x ) : → { − 1 , + 1 } G_m(x): \rightarrow \{ -1,+1\} Gm(x):{1,+1}
    2. 计算 G m ( x ) G_m(x) Gm(x)在训练数据集上的分类误差率
      e m = P ( G m ( x i ) ≠ y i ) = ∑ i = 1 N w m i I ( G m ( x i ) ≠ y i ) e_m = P(G_m(x_i) \neq y_i)=\sum_{i=1}^{N}w_{mi}I(G_m(x_i)\neq y_i) em=P(Gm(xi)=yi)=i=1NwmiI(Gm(xi)=yi)
    3. 计算 G m ( x ) G_m(x) Gm(x)的系数
      α m = 1 2 log ⁡ 1 − e m e m \alpha_m = \dfrac{1}{2} \log{\dfrac{1-e_m}{e_m}} αm=21logem1em
      这里的对数是自然对数
    4. 更新训练数据集的权值分布
      D m + 1 = ( w m + 1 , 1 , . . . , w m + 1 , i , . . . , w m + 1 , N ) D_{m+1}=(w_{m+1,1},...,w_{m+1,i},...,w_{m+1,N}) Dm+1=(wm+1,1,...,wm+1,i,...,wm+1,N)
      w m + 1 , i = w m i Z m exp ⁡ ( − α m y i G m ( x i ) ) , i = 1 , 2 , . . . , N w_{m+1,i}=\dfrac{w_{mi}}{Z_m}\exp{(-\alpha_m y_i G_m(x_i))},i=1,2,...,N wm+1,i=Zmwmiexp(αmyiGm(xi)),i=1,2,...,N
      这里, Z m Z_m Zm是规范化因子
      Z m = ∑ i = 1 N w m i exp ⁡ ( − α m y i G m ( x i ) ) Z_m=\sum_{i=1}^{N}w_{mi}\exp{(-\alpha_m y_i G_m(x_i))} Zm=i=1Nwmiexp(αmyiGm(xi))
      它使 D m + 1 D_{m+1} Dm+1成为一个 概率分布
  3. 构建基本分类器的线性组合
    f ( x ) = ∑ m = 1 M α m G m ( x ) f(x)=\sum_{m=1}^{M}\alpha_mG_m(x) f(x)=m=1MαmGm(x)
    得到最终分类器
    G ( x ) = s i g n ( f ( x ) ) = s i g n ( ∑ m = 1 M α m G m ( x ) ) G(x)=sign (f(x))=sign (\sum_{m=1}^{M}\alpha_mG_m(x)) G(x)=sign(f(x))=sign(m=1MαmGm(x))

2.2 SAMME

SAMME算法的全称是 S t a g e w i s e   A d d i t i v e   M o d e l i n g   u s i n g   a   M u l t i c l a s s   E x p o n e n t i a l   l o s s   f u n c t i o n \rm{\textbf{S}tagewise\,\textbf{A}dditive\,\textbf{M}odeling\, using\, a\,\textbf{M}ulticlass\,\textbf{E}xponential\, loss\, function} StagewiseAdditiveModelingusingaMulticlassExponentiallossfunction,它假定模型的总输出 f \mathbf{f} f具有 f ( M ) ( x ) = ∑ m = 1 M β ( m ) b ( m ) ( x ) \mathbf{f}^{(M)}(\mathbf{x})=\sum_{m=1}^M \beta^{(m)} \mathbf{b}^{(m)}(\mathbf{x}) f(M)(x)=m=1Mβ(m)b(m)(x)的形式。其中, M M M是模型的总迭代轮数, β ( m ) ∈ R + \beta^{(m)}\in \mathbb{R^+} β(m)R+是每轮模型的加权系数, b ( m ) ( x ) ∈ R K \mathbf{b}^{(m)}(\mathbf{x}) \in\mathbb{R}^K b(m)(x)RK是基模型 G G G输出类别的标签向量。

算法流程如下图
在这里插入图片描述
【思考题】对公式进行化简,写出 K = 2 K=2 K=2时的SAMME算法流程,并与李航《统计学习方法》一书中所述的Adaboost二分类算法对比是否一致。

就是将含K的项可以去掉,因为 ( K − 1 ) 2 K \dfrac{(K-1)^2}{K} K(K1)2 K = 2 K=2 K=2时为1,而 log ⁡ ( K − 1 ) \log{(K-1)} log(K1) K = 2 K=2 K=2时为0。化简结果和二分类一致,具体见2.1。

2.3 SAMME的代码实现

导入基础库

import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification

定义类

class AdaBoost:
    def __init__(self, n_estimators=100):
        self.clf_num = n_estimators
        self.classes = None
        
    def init_args(self, X, y):
    #初始化参数
        self.X = X
        self.y = y
        
        M, _ = X.shape
        
        self.models = []
        self.alphas = []
        self.weights = np.repeat(1/X.shape[0],X.shape[0])
        
        self.classes = np.unique(y.reshape(-1)).shape[0]
        
    def fit(self, X, y):
        self.init_args(X, y)
        output = 0
        
        for n in range(self.clf_num):
            #基础分类器
            clf = DecisionTreeClassifier(max_depth=1)
            clf.fit(X, y, sample_weight=self.weights)
            P = clf.predict(X)
            
            #误差计算
            err = (self.weights*(P!=y)).sum()
            #误差权重计算
            alpha = np.log((1-err)/err)+np.log(self.classes-1)
            
            #生成输出结果,对应于argmax形式
            temp_output = np.full((X.shape[0],self.classes),
                                  -1/(self.classes-1))
            temp_output[np.arange(X.shape[0]),P] = 1
            
            self.models.append(clf)
            self.alphas.append(alpha)
            
            #更新权重
            self.weights *= np.exp(alpha * (y != P))
            self.weights /= self.weights.sum()
            
            #更新输出
            output += temp_output * alpha
        
        #acc = accuracy_score(y,np.argmax(output, axis = 1))
        #print(acc)
        
    def predict(self,X):
    #预测过程不需要计算误差,只需要不断更新输出即可
        result = 0
        for n in range(self.clf_num):
            cur_pred = self.models[n].predict(X)
            temp_output = np.full((X.shape[0],self.classes),
                                  -1/(self.classes-1))
            temp_output[np.arange(X.shape[0]),cur_pred] = 1
            
            result += self.alphas[n] * temp_output
            
        return np.argmax(result,axis=1)

随后进行测试,与sklearn自带的进行对比。

X, y = make_classification(
        n_samples=10000, n_features=10,
        n_informative=5, random_state=0, n_classes=2
    )

X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.3, random_state=0
    )

from sklearn.ensemble import AdaBoostClassifier as ABC
clf = ABC(
        DecisionTreeClassifier(max_depth=1),
        n_estimators=20, algorithm="SAMME"
    )
clf.fit(X_train, y_train)
result = clf.predict(X_test)
print("sklearn中SAMME的验证集得分为: ", accuracy_score(y_test, result))

clf = AdaBoost(20)
clf.fit(X_train, y_train)
result = clf.predict(X_test)
print("SAMME的验证集得分为: ", accuracy_score(y_test, result))

预测结果
在这里插入图片描述

3 Adaboost.R2

这是用于处理回归问题的最常使用的AdaBoost方法。
需要重新定义误差的表达形式

设训练集特征和目标分别为 X = ( x 1 , . . . , x n ) \mathbf{X}=(\mathbf{x}_1, ..., \mathbf{x}_n) X=(x1,...,xn) y = ( y 1 , . . . , y n ) \mathbf{y}=(y_1,...,y_n) y=(y1,...,yn),权重 w \mathbf{w} w初始化为 ( w 1 , . . . , w n ) (w_1,...,w_n) (w1,...,wn)。在第 m m m轮时,根据权重训练基预测器得到 G ∗ G^* G,计算每个样本的相对误差
e i = ∣ y i − G ∗ ( x i ) ∣ max ⁡ i ∣ y i − G ∗ ( x i ) ∣ e_{i}=\frac{\vert y_i-G^*(\mathbf{x}_i)\vert}{\max_i \vert y_i-G^*(\mathbf{x}_i)\vert} ei=maxiyiG(xi)yiG(xi)
设样本的加权相对误差率为 E ( m ) = ∑ i = 1 n w i e i E^{(m)}=\sum_{i=1}^n w_ie_i E(m)=i=1nwiei,则相对误差率与正确率的比值为 β ( m ) = E ( m ) 1 − E ( m ) \beta^{(m)}=\frac{E^{(m)}}{1-E^{(m)}} β(m)=1E(m)E(m),即预测器权重 α ( m ) = log ⁡ 1 β ( m ) \alpha^{(m)}=\log \frac{1}{\beta^{(m)}} α(m)=logβ(m)1

训练算法如下
在这里插入图片描述

4 知识回顾

  1. 二分类问题下,AdaBoost算法如何调节样本权重?
    根据分类误差,每一轮训练都放大错误预测样本的权重。
  2. 样本A在当轮分类错误,且样本B在当轮分类正确,请问在权重调整后,样本A的权重一定大于样本B吗?
    不是,因为样本权重是一个累积值,在整个boosting的过程中不断累积,由于未知样本A和样本B在本轮开始前的权重情况,因此不能知道该轮分类正确与否对样本权重的影响。
  3. 在处理分类问题时,Adaboost的损失函数是什么?请叙述其设计的合理性。
    AdaBoost选用的损失函数是 L ( y , f ) = exp ⁡ ( − y T f K ) L(\mathbf{y},\mathbf{f})=\exp(-\frac{\mathbf{y}^T\mathbf{f}}{K}) L(y,f)=exp(KyTf)

参考文献

  1. 机器学习算法之Boosting
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SheltonXiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值