【树模型与集成学习】(task5)自适应提升法AdaBoost(更新ing)

简介: 自适应提升算法Adaboost,Adaptive Boosting。自适应是指Adaboost会根据本轮样本的误差结果来分配下一轮模型训练时样本在模型中的相对权重,即对错误的或偏差大的样本适度“重视”,对正确的或偏差小的样本适度“放松”,这里的“重视”和“放松”具体体现在了Adaboost的损失函数设计以及样本权重的更新策略。

一、Adaboost概述

自适应提升算法Adaboost,Adaptive Boosting。

自适应是指Adaboost会根据本轮样本的误差结果来分配下一轮模型训练时样本在模型中的相对权重,即对错误的或偏差大的样本适度“重视”,对正确的或偏差小的样本适度“放松”,这里的“重视”和“放松”具体体现在了Adaboost的损失函数设计以及样本权重的更新策略。


1.1 一个栗子

【对Adaboost的通俗理解】

就像是做错题本,把每次把错题做一次,然后组成一本新的“错题本2”,依次类推,然后得到错题本n,直到所有的题目都能重做做对位置。


【对梯度提升的通俗理解】

而对于梯度提升,类似AdaBoost算法,它是拟合上一个模型预测错误的实例,即拟合上一个模型的残差(Residual Errors)。举个栗子说,做错题,但是这次不再收集错题了,是m每次查看做错的题目是从哪一步开始做错,然后从这一步开始,重新编制一道新的题目。新题的解题步骤就从做错的那一步开始,以此类推组成了一种新形式的错题本,直到将所有的题目都做对。


也就是说梯度提升是首先预测一个模型,进行预测,然后计算残差,让这些残差成为新的训练样本。用一个新模型去拟合这些残差,以此类推。最后将这一过程的所有模型累加得到最终模型。


1.2 AdaBoost二分类

(此处1.2参考李航老师的《统计学习方法》)

input:训练数据集

image.png

其中image.png标记image.png

output:最终分类器G ( x ) G(x)G(x)。


AdaBoost就是从训练数据中学习一系列弱分类器或者基本分类器,并将这些弱分类器线性组合成一个强分类器。具体过程:

(1)初始化训练数据的权值分布:


image.png

(2)对m=1,2,3,…,M

(2.1)使用具有权值分布D m D_mD

m

的训练数据集学习,得到基本分类器


image.png

image.png

(2.2)计算G m ( x ) G_{m}(x)G

m

(x)在训练数据集上的分类误差率

image.png

(2.3)计算G m ( x ) G_{m}(x)G

m

(x)的系数

image.png

这里的对数是自然对数。

(2.4)更新训练数据集的权值分布

image.png

这里的Z m Z_{m}Z

m

是规范化因子:

image.png

(3)构建基本分类器的线性组合

image.png

得到最终分类器:

image.png

二、分类损失

image.png

上面的计算也可以通过python计算:

>>> import math
>>> math.exp(0.15)
1.161834242728283

image.png

因此,选择指数损失能够满足贝叶斯最优决策条件。


三、SAMME算法

3.1 SAMME算法的motivation

根据Adaboost算法更新权重的原理我们知道想要在下一轮训练中使误分类的样本的权重增加,每一轮训练的错误率都必须小于0.5,包括初始化分类器时也是如此。初始化一般都是随机初始化,对于二分类任务,每个样本都有0.5的概率被预测正确,要达到0.5以上的正确率还是比较容易的,但是对于多分类问题就不一样了,在多分类问题中如果有 K个不同的类别,那么随机猜测只有 1/K 的概率预测正确,因此若直接将Adaboost算法应用于多类分类问题往往不能得到令人满意的结果。针对这个问题,Zhu Ji等人在2009年提出了SAMME及SAMME.R算法,这也是sklearn中用Adaboost做多类分类问题时采用的算法。


有几个基础知识:


(1)加法模型

image.png

这里的大G是每一轮训练的分类器的误差,α \alphaα是该分类器的权重。


(2)弱学习与强学习

弱学习:识别错误率小于1/2(即准确率仅比随机猜测略高的学习算法)

强学习:识别准确率很高并能在多项式时间内完成的学习算法

一个概念是强可学习的充分必要条件是这个概念是弱可学习


(3)权重更新公式

3.2 Adaboost的SAMME实现

  • AdaBoost有一种解释,即可以认为它是模型为加法模型、损失函数为指数函数、学习算法为前向分步算法的二分类学习方法。image.pngimage.pngimage.pngimage.png【练习】对公式进行化简,写出K = 2 K=2K=2时的SAMME算法流程,并与李航《统计学习方法》一书中所述的Adaboost二分类算法对比是否一致。

【答】一致。


3.3 SAMME算法迭代循环的优化

还能通过一些多分类的性质来改写算法的局部实现,使得一些变量前的系数得到简化。记

image.png

来代替b ∗ ( m ) ( x ) \mathbf{b}^{*(m)}(\mathbf{x})b

∗(m)

(x)。请根据本文的实现,对sklearn包的源码进行修改并构造一个例子来比较它们的输出是否会不同。(提示:修改AdaboostClassifier类中的decision_function函数和staged_decision_function函数)



1

对w \mathbf{w}w进行归一化操作后,不会对下一轮算法1中G ∗ G^*G

和e r r ( m ) err^{(m)}err

(m)

的结果产生任何影响。同时,如果把算法1第12行的β ∗ ( m ) \beta^{*(m)}β

∗(m)

替换为α ∗ ( m ) \alpha^{*(m)}α

∗(m)

,由于它们的输出结果只相差常数倍

image.png来更新,而不影响归一化结果。此时,算法1的迭代循环可进行如下重写:

image.png


四、SAMME.R算法

许多分类器都能够输出预测样本所属某一类别的概率,但是SAMME算法只能利用分类的标签信息,而不能利用这样的概率信息。SAMME.R算法通过损失近似的思想,将加权分类模型的概率输出信息与boosting方法相结合。SAMME.R中的字母“R”代表“Real”,意味着模型每轮迭代的输出为实数。image.pngimage.pngimage.png【练习】验证h k ′ ∗ h^*_{k'}h

k

的求解结果。

【练习】算法3的第14行给出了w i w_iw

i

的更新策略,请说明其合理性。


将上述算法过程总结伪代码如下:



五、SAMME和SAMME.R代码实现

import numpy as np
from sklearn.metrics import accuracy_score
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
class AdaboostClassifier:
    def __init__(self, base_estimator, n_estimators, algorithm):
        self.base_estimator = base_estimator
        self.n_estimators = n_estimators
        self.algorithm = algorithm
        self.boostors = []
        if self.algorithm == "SAMME":
            self.boostor_weights = []
        self.classes = None
    def fit(self, X, y, **kwargs):
        w = np.repeat(1/X.shape[0], X.shape[0])
        self.classes = np.unique(y.reshape(-1)).shape[0]
        output = 0
        for n in range(self.n_estimators):
            cur_boostor = self.base_estimator(**kwargs)
            cur_boostor.fit(X, y, w)
            if self.algorithm == "SAMME":
                y_pred = cur_boostor.predict(X)
                err = (w*(y != y_pred)).sum()
                alpha = np.log((1-err)/err) + np.log(self.classes-1)
                temp_output = np.full(
                    (X.shape[0], self.classes), -1/(self.classes-1))
                temp_output[np.arange(X.shape[0]), y_pred] = 1
                # 把当前轮的基模型和模型权重加入列表,准备预测的时候用
                self.boostors.append(cur_boostor)
                self.boostor_weights.append(alpha)
                w *= np.exp(alpha * (y != y_pred))
                w /= w.sum()
                output += temp_output * alpha
            elif self.algorithm == "SAMME.R":
                y_pred = cur_boostor.predict_proba(X)
                log_proba = np.log(y_pred + 1e-6)
                temp_output = (
                    self.classes-1)*(log_proba-log_proba.mean(1).reshape(-1,1))
                temp_y = np.full(
                    (X.shape[0], self.classes), -1/(self.classes-1))
                temp_y[np.arange(X.shape[0]), y] = 1
                self.boostors.append(cur_boostor)
                w *= np.exp(
                    (1-self.classes)/self.classes * (temp_y*log_proba).sum(1))
                w /= w.sum()
                output += temp_output
            #acc = accuracy_score(y, np.argmax(output, axis=1))
            #print(acc)
    def predict(self, X):
        result = 0
        if self.algorithm == "SAMME":
            for n in range(self.n_estimators):
                cur_pred = self.boostors[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.boostor_weights[n] * temp_output
        elif self.algorithm == "SAMME.R":
            for n in range(self.n_estimators):
                y_pred = self.boostors[n].predict_proba(X)
                log_proba = np.log(y_pred + 1e-6)
                temp_output = (
                    self.classes-1)*(log_proba-log_proba.mean(1).reshape(-1,1))
                result += temp_output
        return np.argmax(result, axis=1)
if __name__ == "__main__":
    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 = AdaboostClassifier(
        DecisionTreeClassifier,
        20, "SAMME"
    )
    clf.fit(X_train, y_train, max_depth=1)
    result = clf.predict(X_test)
    print("使用SAMME.R集成的验证集得分为: ", accuracy_score(y_test, result))
    clf = ABC(
        DecisionTreeClassifier(max_depth=1),
        n_estimators=20, algorithm="SAMME.R"
    )
    clf.fit(X_train, y_train)
    result = clf.predict(X_test)
    print("sklearn中SAMME.R的验证集得分为: ", accuracy_score(y_test, result))
    clf = AdaboostClassifier(
        DecisionTreeClassifier,
        20, "SAMME.R"
    )
    clf.fit(X_train, y_train, max_depth=1)
    result = clf.predict(X_test)
    print("使用SAMME.R集成的验证集得分为: ", accuracy_score(y_test, result))
    clf = DecisionTreeClassifier(max_depth=1)
    clf.fit(X_train, y_train)
    result = clf.predict(X_test)
    print("使用决策树桩的验证集得分为: ", accuracy_score(y_test, result))
sklearn中SAMME的验证集得分为:  0.8316666666666667
使用SAMME.R集成的验证集得分为:  0.8316666666666667
sklearn中SAMME.R的验证集得分为:  0.8503333333333334
使用SAMME.R集成的验证集得分为:  0.8503333333333334
使用决策树桩的验证集得分为:  0.7746666666666666

六、Adaboost.R2算法(回归)

利用权重重分配的思想,Adaboost还可以应用于处理回归问题。其中,Adaboost.R2算法是一种最常使用的实现。

image.png

image.png七、作业

1. 二分类问题下,Adaboost算法如何调节样本的权重?

input:训练数据集

image.pngimage.pngimage.pngimage.png

4.Adaboost如何处理回归问题?

利用权重重分配的思想,Adaboost还可以应用于处理回归问题。其中,Adaboost.R2算法是一种最常使用的实现。

image.png

image.png

5.用已训练的Adaboost分类模型和回归模型来预测新样本的标签,请分别具体描述样本从输入到标签输出的流程。

(1)分类的预测过程

(2)回归的预测过程image.png

相关文章
|
19天前
|
定位技术
【视频】Boosting集成学习原理与R语言提升回归树BRT预测短鳍鳗分布生态学实例-3
【视频】Boosting集成学习原理与R语言提升回归树BRT预测短鳍鳗分布生态学实例
|
19天前
|
机器学习/深度学习 缓存 算法
【视频】Boosting集成学习原理与R语言提升回归树BRT预测短鳍鳗分布生态学实例-2
【视频】Boosting集成学习原理与R语言提升回归树BRT预测短鳍鳗分布生态学实例
|
11天前
|
传感器 数据采集 数据处理
MATLAB热传导方程模型最小二乘法模型、线性规划对集成电路板炉温优化
MATLAB热传导方程模型最小二乘法模型、线性规划对集成电路板炉温优化
|
11天前
|
机器学习/深度学习 算法 前端开发
【Python机器学习专栏】集成学习中的Bagging与Boosting
【4月更文挑战第30天】本文介绍了集成学习中的两种主要策略:Bagging和Boosting。Bagging通过自助采样构建多个基学习器并以投票或平均法集成,降低模型方差,增强稳定性。在Python中可使用`BaggingClassifier`实现。而Boosting是串行学习,不断调整基学习器权重以优化拟合,适合弱学习器。Python中可利用`AdaBoostClassifier`等实现。示例代码展示了如何在实践中运用这两种方法。
|
11天前
|
机器学习/深度学习 算法 前端开发
【Python机器学习专栏】集成学习算法的原理与应用
【4月更文挑战第30天】集成学习通过组合多个基学习器提升预测准确性,广泛应用于分类、回归等问题。主要步骤包括生成基学习器、训练和结合预测结果。算法类型有Bagging(如随机森林)、Boosting(如AdaBoost)和Stacking。Python中可使用scikit-learn实现,如示例代码展示的随机森林分类。集成学习能降低模型方差,缓解过拟合,提高预测性能。
|
18天前
|
机器学习/深度学习 算法
大模型开发:描述集成学习以及它如何工作。
【4月更文挑战第24天】集成学习通过结合多个模型预测提升整体性能,减少偏差和方差。主要分为Bagging和Boosting两类。Bagging中,模型并行在数据子集上训练,如随机森林,通过投票或平均聚合预测。Boosting则顺序训练模型,聚焦纠正前一个模型的错误,如AdaBoost,加权组合所有模型预测。Stacking则是用基础模型的输出训练新模型。关键在于模型多样性以捕捉数据不同模式。集成学习广泛应用于分类、回归等任务,能提高泛化能力,降低过拟合风险。
15 3
|
19天前
|
机器学习/深度学习 算法
【视频】Boosting集成学习原理与R语言提升回归树BRT预测短鳍鳗分布生态学实例-1
【视频】Boosting集成学习原理与R语言提升回归树BRT预测短鳍鳗分布生态学实例
|
23天前
|
数据可视化 Python
Python进行多输出(多因变量)回归:集成学习梯度提升决策树GRADIENT BOOSTING,GBR回归训练和预测可视化
Python进行多输出(多因变量)回归:集成学习梯度提升决策树GRADIENT BOOSTING,GBR回归训练和预测可视化
Python进行多输出(多因变量)回归:集成学习梯度提升决策树GRADIENT BOOSTING,GBR回归训练和预测可视化
|
23天前
|
机器学习/深度学习 数据采集 算法
ARMA-EGARCH模型、集成预测算法对SPX实际波动率进行预测
ARMA-EGARCH模型、集成预测算法对SPX实际波动率进行预测
|
24天前
|
机器学习/深度学习 存储 算法
PYTHON集成机器学习:用ADABOOST、决策树、逻辑回归集成模型分类和回归和网格搜索超参数优化
PYTHON集成机器学习:用ADABOOST、决策树、逻辑回归集成模型分类和回归和网格搜索超参数优化

热门文章

最新文章