AdaBoost(Adaptive Boosting)算法

一、概念

AdaBoost(自适应提升)是一种集成学习(Ensemble Learning)算法 ,属于Boosting家族。其核心思想是:通过迭代训练一系列"弱分类器"(性能略优于随机猜测,如决策树桩),并根据每个弱分类器的表现赋予不同权重,最终将它们加权组合成一个"强分类器"

"自适应"体现在:每个弱分类器训练时,会自适应地调整样本权重------前一个分类器错分的样本权重会被放大,使得下一个分类器更关注这些难分样本,从而逐步提升整体性能。

二、核心理论

AdaBoost的工作流程可概括为4步迭代过程:

  1. 初始化样本权重 :所有样本初始权重相等(如 wi=1/Nw_i = 1/Nwi=1/N,NNN 为样本数)。
  2. 训练弱分类器 :基于当前样本权重,训练一个弱分类器 hm(x)h_m(x)hm(x)(第 mmm 轮迭代的分类器),目标是最小化带权重的分类错误。
  3. 计算弱分类器权重 :根据弱分类器的错误率 ϵm\epsilon_mϵm,计算其在最终强分类器中的权重 αm\alpha_mαm(错误率越低,权重越高)。
  4. 更新样本权重:对正确分类的样本降低权重,错分样本提高权重(使下一轮更关注错分样本),并归一化权重以保证总和为1。

重复步骤2-4,直到训练出预设数量的弱分类器(如 MMM 个),最终强分类器为所有弱分类器的加权投票(分类任务)或加权求和(回归任务)。

三、数学公式
1. 样本权重初始化

设训练集为 {(x1,y1),(x2,y2),...,(xN,yN)}\{(x_1,y_1), (x_2,y_2), ..., (x_N,y_N)\}{(x1,y1),(x2,y2),...,(xN,yN)},其中 yi∈{−1,1}y_i \in \{-1, 1\}yi∈{−1,1}(二分类,正类1,负类-1),初始权重为:
w1,i=1N(i=1,2,...,N) w_{1,i} = \frac{1}{N} \quad (i=1,2,...,N) w1,i=N1(i=1,2,...,N)

2. 弱分类器错误率

第 mmm 轮迭代中,弱分类器 hm(x):X→{−1,1}h_m(x): X \to \{-1, 1\}hm(x):X→{−1,1} 的带权重错误率为:
ϵm=∑i=1Nwm,i⋅I(hm(xi)≠yi) \epsilon_m = \sum_{i=1}^N w_{m,i} \cdot I(h_m(x_i) \neq y_i) ϵm=i=1∑Nwm,i⋅I(hm(xi)=yi)

其中 I(⋅)I(\cdot)I(⋅) 为指示函数(条件成立时为1,否则为0),wm,iw_{m,i}wm,i 为第 mmm 轮样本 iii 的权重。

3. 弱分类器权重

第 mmm 个弱分类器的权重 αm\alpha_mαm 由其错误率决定(错误率越低,权重越高):
αm=12log⁡(1−ϵmϵm) \alpha_m = \frac{1}{2} \log\left( \frac{1 - \epsilon_m}{\epsilon_m} \right) αm=21log(ϵm1−ϵm)

(推导见下文,核心是最小化损失函数)。

4. 样本权重更新

第 mmm 轮迭代后,样本 iii 的权重更新为:
wm+1,i=wm,i⋅exp⁡(−αm⋅yi⋅hm(xi))Zm w_{m+1,i} = \frac{w_{m,i} \cdot \exp\left( -\alpha_m \cdot y_i \cdot h_m(x_i) \right)}{Z_m} wm+1,i=Zmwm,i⋅exp(−αm⋅yi⋅hm(xi))

其中 ZmZ_mZm 为归一化因子(确保权重和为1):
Zm=∑i=1Nwm,i⋅exp⁡(−αm⋅yi⋅hm(xi)) Z_m = \sum_{i=1}^N w_{m,i} \cdot \exp\left( -\alpha_m \cdot y_i \cdot h_m(x_i) \right) Zm=i=1∑Nwm,i⋅exp(−αm⋅yi⋅hm(xi))

更新逻辑:若 hm(xi)=yih_m(x_i) = y_ihm(xi)=yi(正确分类),则 yi⋅hm(xi)=1y_i \cdot h_m(x_i) = 1yi⋅hm(xi)=1,权重乘以 exp⁡(−αm)\exp(-\alpha_m)exp(−αm)(降低);若错分,则乘以 exp⁡(αm)\exp(\alpha_m)exp(αm)(升高)。

5. 强分类器

MMM 个弱分类器加权组合得到强分类器 H(x)H(x)H(x):
H(x)=sign(∑m=1Mαm⋅hm(x)) H(x) = \text{sign}\left( \sum_{m=1}^M \alpha_m \cdot h_m(x) \right) H(x)=sign(m=1∑Mαm⋅hm(x))

其中 sign(⋅)\text{sign}(\cdot)sign(⋅) 为符号函数(输出1或-1)。

四、推导过程(核心公式推导)

AdaBoost的推导基于指数损失函数 (Exponential Loss),目标是通过最小化损失函数确定弱分类器权重 αm\alpha_mαm 和样本权重更新规则。

1. 指数损失函数

设强分类器在第 mmm 轮的输出为 Hm(x)=Hm−1(x)+αmhm(x)H_m(x) = H_{m-1}(x) + \alpha_m h_m(x)Hm(x)=Hm−1(x)+αmhm(x)(逐步叠加弱分类器),损失函数定义为:
L(Hm)=∑i=1Nexp⁡(−yiHm(xi)) L(H_m) = \sum_{i=1}^N \exp\left( -y_i H_m(x_i) \right) L(Hm)=i=1∑Nexp(−yiHm(xi))

2. 弱分类器权重 αm\alpha_mαm 的推导

将 Hm(x)=Hm−1(x)+αmhm(x)H_m(x) = H_{m-1}(x) + \alpha_m h_m(x)Hm(x)=Hm−1(x)+αmhm(x) 代入损失函数:
L(Hm)=∑i=1Nexp⁡(−yi(Hm−1(xi)+αmhm(xi)))=∑i=1Nexp⁡(−yiHm−1(xi))⋅exp⁡(−αmyihm(xi)) L(H_m) = \sum_{i=1}^N \exp\left( -y_i (H_{m-1}(x_i) + \alpha_m h_m(x_i)) \right) = \sum_{i=1}^N \exp\left( -y_i H_{m-1}(x_i) \right) \cdot \exp\left( -\alpha_m y_i h_m(x_i) \right) L(Hm)=i=1∑Nexp(−yi(Hm−1(xi)+αmhm(xi)))=i=1∑Nexp(−yiHm−1(xi))⋅exp(−αmyihm(xi))

令 wm,i=exp⁡(−yiHm−1(xi))/Zm−1w_{m,i} = \exp\left( -y_i H_{m-1}(x_i) \right) / Z_{m-1}wm,i=exp(−yiHm−1(xi))/Zm−1(归一化后的权重,Zm−1Z_{m-1}Zm−1 为常数),则损失函数可写为:
L(Hm)=Zm−1∑i=1Nwm,i⋅exp⁡(−αmyihm(xi)) L(H_m) = Z_{m-1} \sum_{i=1}^N w_{m,i} \cdot \exp\left( -\alpha_m y_i h_m(x_i) \right) L(Hm)=Zm−1i=1∑Nwm,i⋅exp(−αmyihm(xi))

忽略常数 Zm−1Z_{m-1}Zm−1,对 αm\alpha_mαm 求导并令导数为0,最小化损失:

  • 当 hm(xi)=yih_m(x_i) = y_ihm(xi)=yi 时,yihm(xi)=1y_i h_m(x_i) = 1yihm(xi)=1,项为 wm,iexp⁡(−αm)w_{m,i} \exp(-\alpha_m)wm,iexp(−αm);
  • 当 hm(xi)≠yih_m(x_i) \neq y_ihm(xi)=yi 时,yihm(xi)=−1y_i h_m(x_i) = -1yihm(xi)=−1,项为 wm,iexp⁡(αm)w_{m,i} \exp(\alpha_m)wm,iexp(αm)。

总损失为 L(αm)=(1−ϵm)exp⁡(−αm)+ϵmexp⁡(αm)L(\alpha_m) = (1 - \epsilon_m) \exp(-\alpha_m) + \epsilon_m \exp(\alpha_m)L(αm)=(1−ϵm)exp(−αm)+ϵmexp(αm),求导得:
dLdαm=−(1−ϵm)exp⁡(−αm)+ϵmexp⁡(αm)=0 \frac{dL}{d\alpha_m} = -(1 - \epsilon_m) \exp(-\alpha_m) + \epsilon_m \exp(\alpha_m) = 0 dαmdL=−(1−ϵm)exp(−αm)+ϵmexp(αm)=0

解得:
exp⁡(2αm)=1−ϵmϵm  ⟹  αm=12log⁡(1−ϵmϵm) \exp(2\alpha_m) = \frac{1 - \epsilon_m}{\epsilon_m} \implies \alpha_m = \frac{1}{2} \log\left( \frac{1 - \epsilon_m}{\epsilon_m} \right) exp(2αm)=ϵm1−ϵm⟹αm=21log(ϵm1−ϵm)

3. 样本权重更新推导

第 m+1m+1m+1 轮的样本权重 wm+1,iw_{m+1,i}wm+1,i 与 exp⁡(−yiHm(xi))\exp(-y_i H_m(x_i))exp(−yiHm(xi)) 成正比:
wm+1,i∝exp⁡(−yiHm(xi))=exp⁡(−yi(Hm−1(xi)+αmhm(xi)))=wm,i⋅Zm−1⋅exp⁡(−αmyihm(xi)) w_{m+1,i} \propto \exp(-y_i H_m(x_i)) = \exp\left( -y_i (H_{m-1}(x_i) + \alpha_m h_m(x_i)) \right) = w_{m,i} \cdot Z_{m-1} \cdot \exp\left( -\alpha_m y_i h_m(x_i) \right) wm+1,i∝exp(−yiHm(xi))=exp(−yi(Hm−1(xi)+αmhm(xi)))=wm,i⋅Zm−1⋅exp(−αmyihm(xi))

归一化后即为:
wm+1,i=wm,i⋅exp⁡(−αmyihm(xi))Zm w_{m+1,i} = \frac{w_{m,i} \cdot \exp\left( -\alpha_m y_i h_m(x_i) \right)}{Z_m} wm+1,i=Zmwm,i⋅exp(−αmyihm(xi))

五、Python实现(AdaBoost分类器,基于决策树桩)

以决策树桩(深度为1的决策树,最简单的弱分类器)为例实现AdaBoost:

python 复制代码
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification
from sklearn.metrics import accuracy_score

# 弱分类器:决策树桩(单特征阈值分类)
class DecisionStump:
    def __init__(self):
        self.theta = None  # 阈值
        self.feature_idx = None  # 特征索引
        self.sign = 1  # 符号(1或-1,决定阈值方向)

    def fit(self, X, y, weights):
        n_samples, n_features = X.shape
        min_error = float('inf')

        # 遍历所有特征
        for idx in range(n_features):
            X_col = X[:, idx]
            thresholds = np.unique(X_col)  # 用特征的唯一值作为候选阈值

            # 遍历所有阈值
            for theta in thresholds:
                # 尝试两种符号(大于阈值为1或-1)
                for sign in [1, -1]:
                    y_pred = sign * np.where(X_col >= theta, 1, -1)  # 预测
                    error = np.sum(weights * (y_pred != y))  # 带权重的错误率

                    # 记录最优参数
                    if error < min_error:
                        min_error = error
                        self.theta = theta
                        self.feature_idx = idx
                        self.sign = sign
                        self.error = min_error

    def predict(self, X):
        X_col = X[:, self.feature_idx]
        return self.sign * np.where(X_col >= self.theta, 1, -1)


# AdaBoost分类器
class AdaBoost:
    def __init__(self, n_estimators=50):
        self.n_estimators = n_estimators  # 弱分类器数量
        self.estimators = []  # 弱分类器列表
        self.alphas = []  # 弱分类器权重

    def fit(self, X, y):
        n_samples = X.shape[0]
        # 初始化样本权重
        weights = np.full(n_samples, 1 / n_samples)

        for _ in range(self.n_estimators):
            # 1. 训练弱分类器(决策树桩)
            stump = DecisionStump()
            stump.fit(X, y, weights)
            self.estimators.append(stump)

            # 2. 计算弱分类器权重
            epsilon = stump.error
            if epsilon >= 0.5:  # 弱分类器性能需优于随机猜测
                break
            alpha = 0.5 * np.log((1 - epsilon) / epsilon)
            self.alphas.append(alpha)

            # 3. 更新样本权重
            y_pred = stump.predict(X)
            weights *= np.exp(-alpha * y * y_pred)  # 错分样本权重增大
            weights /= np.sum(weights)  # 归一化

    def predict(self, X):
        # 所有弱分类器加权求和
        final_pred = np.sum(alpha * clf.predict(X) for alpha, clf in zip(self.alphas, self.estimators))
        return np.sign(final_pred)  # 符号函数输出分类结果


# 测试代码
if __name__ == "__main__":
    # 生成二分类数据(标签转为-1和1)
    X, y = make_classification(n_samples=1000, n_features=10, n_classes=2, random_state=42)
    y = np.where(y == 0, -1, 1)  # AdaBoost通常用-1/1表示标签
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # 训练模型
    model = AdaBoost(n_estimators=50)
    model.fit(X_train, y_train)

    # 预测与评估
    y_pred = model.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
    print(f"自定义AdaBoost准确率:{accuracy:.4f}")  # 约 0.90-0.95
六、sklearn实现

sklearn的 AdaBoostClassifier 支持多类分类,默认弱分类器为决策树桩(DecisionTreeClassifier(max_depth=1)),主要参数包括:

  • base_estimator:弱分类器类型(默认决策树桩);
  • n_estimators:弱分类器数量(默认50);
  • learning_rate:学习率(缩放弱分类器权重,默认1.0)。
示例(乳腺癌分类数据集)
python 复制代码
from sklearn.ensemble import AdaBoostClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 加载数据(标签转为-1和1,或保持0/1均可,sklearn内部兼容)
data = load_breast_cancer()
X, y = data.data, data.target
y = np.where(y == 0, -1, 1)  # 转为-1/1(可选)

# 拆分数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 初始化模型(50个弱分类器,学习率1.0)
model = AdaBoostClassifier(n_estimators=50, learning_rate=1.0, random_state=42)

# 训练
model.fit(X_train, y_train)

# 预测
y_pred = model.predict(X_test)

# 评估
accuracy = accuracy_score(y_test, y_pred)
print(f"sklearn AdaBoost准确率:{accuracy:.4f}")  # 约 0.96-0.98
七、总结
  • 优点:无需手动设计弱分类器(默认决策树桩即可);对噪声不敏感(相比其他Boosting算法);可解释性较强(弱分类器权重反映重要性)。
  • 缺点:训练时间随弱分类器数量增加而增长;对异常值敏感(错分样本权重持续放大);难以处理高维稀疏数据(需配合特征选择)。
  • 适用场景:二分类/多分类任务(如欺诈检测、图像识别),尤其适合中等规模数据集。
相关推荐
江畔柳前堤23 分钟前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore2 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考3 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX4 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面4 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号5 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽5 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI5 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者7 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者7 小时前
【征程6】校准量化中HistogramObserver解析
算法