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算法);可解释性较强(弱分类器权重反映重要性)。
  • 缺点:训练时间随弱分类器数量增加而增长;对异常值敏感(错分样本权重持续放大);难以处理高维稀疏数据(需配合特征选择)。
  • 适用场景:二分类/多分类任务(如欺诈检测、图像识别),尤其适合中等规模数据集。
相关推荐
南方的狮子先生2 小时前
【数据结构】(C++数据结构)查找算法与排序算法详解
数据结构·c++·学习·算法·排序算法·1024程序员节
前进的李工3 小时前
LeetCode hot100:560 和为k的子数组:快速统计法
python·算法·leetcode·前缀和·哈希表
在等晚安么3 小时前
力扣面试经典150题打卡
java·数据结构·算法·leetcode·面试·贪心算法
AndrewHZ4 小时前
【图像处理基石】图像滤镜的算法原理:从基础到进阶的技术解析
图像处理·python·opencv·算法·计算机视觉·滤镜·cv
lxmyzzs4 小时前
【图像算法 - 30】基于深度学习的PCB板缺陷检测系统: YOLOv11 + UI界面 + 数据集实现
人工智能·深度学习·算法·yolo·缺陷检测
gihigo19984 小时前
基于萤火虫算法(FA)优化支持向量机(SVM)参数的分类实现
算法·支持向量机·分类
py有趣5 小时前
LeetCode算法学习之移动0
学习·算法·leetcode
lixinnnn.5 小时前
算法总结篇(枚举-分治)
算法·1024程序员节
on_pluto_5 小时前
【基础复习3】决策树
算法·决策树·机器学习