查看全课大纲(第 31 / 82 节)
  1. 1.函数与数据泛化
  2. 2.向量:从几何直觉到高维空间
  3. 3.矩阵与张量
  4. 4.特征值与特征向量:矩阵变换的不动方向
  5. 5.凸函数:从向量求导的矩阵记号到好优化的函数形状
  6. 6.概率与统计:机器学习的数学基础
  7. 7.独立性与随机变量:贝叶斯公式与二项分布
  8. 8.期望、方差与协方差:随机变量的数字画像
  9. 9.联合概率:当一条轴不够用的时候
  10. 10.概率分布(一):从伯努利到伽马函数
  11. 11.概率分布(二):贝塔、泊松、正态与两个贝叶斯故事
  12. 12.机器学习的模型:找输入与输出的关系
  13. 13.机器学习的应用
  14. 14.过拟合
  15. 15.机器学习的分类
  16. 16.有监督学习:从房价预测说起
  17. 17.损失函数
  18. 18.梯度下降(上):更新规则与学习速率
  19. 19.梯度下降(2)
  20. 20.牛顿方法
  21. 21.KNN简介
  22. 22.距离测算
  23. 23.朴素贝叶斯
  24. 24.朴素贝叶斯的实际应用
  25. 25.信息熵:决策树构建的度量基础
  26. 26.信息增益与决策树的构建
  27. 27.ID3算法
  28. 28.决策树节点的划分
  29. 29.CART树
  30. 30.Bagging
  31. 31.Boosting:自适应提升算法
  32. 32.Gradient Boosting
  33. 33.线性模型:回归与分类的同一副骨架
  34. 34.最小二乘:把最优参数直接解出来
  35. 35.最小二乘法的几何与概率视角
  36. 36.极大似然:给最小二乘一个概率出身
  37. 37.逻辑回归(1):把线性模型接到分类上
  38. 38.逻辑回归(2):损失函数与多分类
  39. 39.---- 手造数据: 5 个样本, 2 个特征; x2 几乎 = 2*x1 (偏差手工指定, 无随机) ----
  40. 40.讲师例: 向量 "23014" -- 三把范数尺子量同一个向量
  41. 41.优化方法(1):坐标下降与前向选择
  42. 42.优化方法(2):前向策略与最小角回归
  43. 43.拉格朗日乘子法(1):从无约束到等式约束
  44. 44.拉格朗日乘子法(2):等式约束下的平行条件与拉格朗日函数
  45. 45.拉格朗日乘子法(3):不等式约束与 KKT 条件
  46. 46.最大间隔:把分类问题变成优化问题
  47. 47.拉格朗日对偶问题:把 w 和 b 全部换成 α
  48. 48.支持向量:边界上的少数派
  49. 49.SVM 计算过程:一笔到底算完,再走进核方法
  50. 50.贝叶斯公式:概率即信念
  51. 51.隐含变量和概率模型:给看不见的原因建模
  52. 52.EM 算法:期望与最大化的迭代
  53. 53.琴生不等式:EM 的数学钥匙
  54. 54.三个硬币问题:EM 的复盘与衔接
  55. 55.高斯混合模型:用隐变量解释双峰数据
  56. 56.隐马尔可夫模型
  57. 57.隐马尔可夫模型(2):前向算法与动态混合模型
  58. 58.隐马尔可夫模型在 NLP 中的运用
  59. 59.EM 算法:把「为什么收敛」推到底
  60. 60.HMM 在 NLP 中的运用:从分词到机器翻译
  61. 61.HMM 参数估计:Baum-Welch 的三块拉格朗日
  62. 62.高维下的高斯模型
  63. 63.主题模型:从词袋到隐含主题
  64. 64.Dirichlet 分布(1)
  65. 65.Dirichlet 分布(2)
  66. 66.统计学习内容回顾
  67. 67.K-means 算法
  68. 68.PCA 降维
  69. 69.SVD 降维
  70. 70.从聚类到流形
  71. 71.局部线性嵌入
  72. 72.随机邻域嵌入:SNE 与 t-SNE
  73. 73.无参模型:让数据自己说话
  74. 74.高斯过程:函数空间里的正态分布
  75. 75.高斯过程(2):噪声、正则化与核的线性组合
  76. 76.神经网络简介:从感知器到自编码器
  77. 77.反向传播:把误差一层层传回去
  78. 78.卷积神经网络(CNN):让特征自己学出来
  79. 79.循环神经网络(RNN):给网络装上记忆
  80. 80.深度学习回顾:静态一类,动态一类
  81. 81.增强学习(1):蒙特卡洛、树搜索与 Q-learning
  82. 82.强化学习(2):从乌鸦吃核桃到井字棋的 value 回传

Boosting:自适应提升算法

约 33 分钟

📺 正在播放小象官方高清录播(支持倍速与清晰度调节)

小象实战讲义 · 机器学习算法精讲

在上一节我们学习了Bagging(装袋法)和随机森林,它们通过并行训练多个模型并投票来提升性能。本节我们将深入探讨另一种强大的集成学习范式——Boosting(提升法)。Boosting的核心思想是顺序地训练一系列“弱”分类器,每个新分类器都专注于纠正前一个分类器犯下的错误,最终将这些弱分类器加权组合成一个强大的“强”分类器。学完本节,你将掌握Boosting(特别是AdaBoost)的工作原理、数学推导,并能亲手实现其核心步骤。

💡 核心导读

  • 串行与并行的本质区别:理解Boosting(顺序、自适应)与Bagging(并行、独立)的根本差异。
  • 双重权重更新机制:掌握如何根据分类误差更新弱分类器的权重,以及如何根据分类结果更新每个样本的权重。
  • AdaBoost算法全流程:从初始化、迭代训练到最终预测,一步步拆解算法的数学公式和实现逻辑。
  • 从直觉到公式:通过可视化示例,直观理解为什么调整样本权重能有效提升模型性能。

Boosting vs. Bagging:哲学与流程对比

Boosting与Bagging虽然同属集成学习,但设计哲学和训练流程截然不同。

  • Bagging (Bootstrap Aggregating):

    • 并行化:从原始数据集中通过有放回抽样生成多个不同的训练子集,每个子集独立训练一个基学习器(如决策树)。这些学习器之间没有依赖关系,可以并行训练。
    • 降低方差:通过平均多个模型的预测,有效减少模型因数据扰动而产生的方差,对过拟合有一定的抑制作用。随机森林是Bagging的典型代表。
  • Boosting (提升法):

    • 序列化:按顺序训练一系列弱学习器。每一个新学习器的训练都依赖于前一个学习器的结果。
    • 聚焦错误:核心机制是样本权重。在每一轮迭代后,算法会增加被前一个弱分类器分错的样本的权重,减少分对样本的权重。这样,下一个弱分类器就会更“关注”那些难以分类的样本。
    • 加权组合:每个弱分类器在最终投票中的话语权(权重) 不同,分类误差越小的弱分类器,其权重越大。
    • 降低偏差:通过不断修正错误,Boosting能够生成一个偏差很低的强学习器。AdaBoost是Boosting家族中最著名的算法之一。

简而言之,讲师用”臭皮匠”给两种集成法画了像:Bagging 的三个臭皮匠人人平等,谁也不比谁好;Boosting 的臭皮匠则分了等级——有厉害点的、有差一点的,最后按本事加权发言;而误差等于瞎猜(ek=0.5e_k=0.5)的”傻子”,连臭皮匠的资格都没有,直接被开除(权重为 0)。

AdaBoost算法详解

AdaBoost(Adaptive Boosting,自适应提升)由Yoav Freund和Robert Schapire于1995年提出。下面我们逐步解析其算法流程、关键公式及背后的动机。

1. 问题设定与初始化

假设我们有一个二分类数据集,包含 NN 个样本:{(x1,y1),(x2,y2),...,(xN,yN)}\lbrace (x_1, y_1), (x_2, y_2), ..., (x_N, y_N) \rbrace,其中 yi∈{−1,+1}y_i \in \lbrace -1, +1\rbrace。 我们计划顺序训练 KK 个弱分类器,记为 g1(x),g2(x),...,gK(x)g_1(x), g_2(x), ..., g_K(x)。

第一步:初始化样本权重。 为每个样本分配初始权重,通常假设所有样本同等重要,即均匀分布: w1,i=1N,对于 i=1,2,...,Nw_{1,i} = \frac{1}{N}, \quad \text{对于 } i = 1, 2, ..., N 这里 wk,iw_{k,i} 表示在第 kk 轮迭代时,第 ii 个样本的权重。

2. 迭代训练:第 kk 轮

对于 k=1,2,...,Kk = 1, 2, ..., K,执行以下步骤:

a) 训练弱分类器 gk(x)g_k(x) 使用当前样本权重分布 wkw_{k} 训练一个弱分类器。这意味着在训练过程中,分类器会更重视权重大的样本。弱分类器可以是任何算法,如深度很小的决策树(Decision Stump)、朴素贝叶斯等。

b) 计算分类误差率 eke_k 误差率不是简单统计错分样本数,而是所有错分样本的权重之和。 ek=∑i=1Nwk,i⋅I(gk(xi)≠yi)e_k = \sum_{i=1}^{N} w_{k,i} \cdot \mathbb{I}(g_k(x_i) \ne y_i) 其中 I(⋅)\mathbb{I}(\cdot) 是指示函数,当括号内条件为真时值为1,否则为0。 因为 ∑i=1Nwk,i=1\sum_{i=1}^N w_{k,i} = 1,所以 eke_k 可以理解为在當前权重分布下,弱分类器犯错的加权概率。

c) 计算弱分类器权重 αk\alpha_k 这是AdaBoost的精髓:为当前弱分类器 gk(x)g_k(x) 分配一个在最终集成模型中的权重 αk\alpha_k。 αk=12ln⁡(1−ekek)\alpha_k = \frac{1}{2} \ln\left(\frac{1 - e_k}{e_k}\right)

  • 公式含义:αk\alpha_k 是 eke_k 的单调递减函数。分类器误差 eke_k 越小,其权重 αk\alpha_k 越大。

讲师带着大家代入几个数来”感受”这条曲线:

  • ek=0.5e_k = 0.5(瞎猜水平):分子分母都是 0.5,αk=12ln⁡1=0\alpha_k = \frac{1}{2}\ln 1 = 0。二分类问题瞎蒙都能蒙对一半,所以 ek=0.5e_k=0.5 的分类器”简直是个傻子”——傻子没有投票权,权重归零。
  • ek=0.2e_k = 0.2(不错的弱分类器):1−0.20.2=4\frac{1-0.2}{0.2} = 4,αk=12ln⁡4\alpha_k = \frac{1}{2}\ln 4。以 2 为底的话 log⁡24=2\log_2 4 = 2,而 ln⁡4\ln 4 比 2 还大——“一个比二大的、很好的结果”。
  • ek=0.1e_k = 0.1:1−0.10.1=9\frac{1-0.1}{0.1} = 9,αk=12ln⁡9\alpha_k = \frac{1}{2}\ln 9,更大。
  • ek→0e_k \to 0(完美分类):αk→+∞\alpha_k \to +\infty——分得越好,话语权越大。实践中需加平滑项避免除零。
  • 如果 ek>0.5e_k > 0.5(比瞎猜还差),则 αk<0\alpha_k < 0:可以把它的预测反转(用 −gk(x)-g_k(x))再加入集成。通常我们要求弱分类器至少略好于瞎猜(ek<0.5e_k < 0.5)。

d) 更新样本权重 wk+1,iw_{k+1,i} 根据当前弱分类器的表现,调整每个样本的权重,为下一轮训练做准备。 wk+1,i=wk,iZk⋅exp⁡(−αk⋅yi⋅gk(xi))w_{k+1,i} = \frac{w_{k,i}}{Z_k} \cdot \exp\left(-\alpha_k \cdot y_i \cdot g_k(x_i)\right) 其中 Zk=∑i=1Nwk,i⋅exp⁡(−αk⋅yi⋅gk(xi))Z_k = \sum_{i=1}^{N} w_{k,i} \cdot \exp\left(-\alpha_k \cdot y_i \cdot g_k(x_i)\right) 是归一化因子,确保更新后的权重之和为1。

  • 更新规则解读:
    • 对于分类正确的样本:yi⋅gk(xi)=+1y_i \cdot g_k(x_i) = +1,则 exp⁡(−αk)\exp(-\alpha_k) 是一个小于1的数(因为 αk>0\alpha_k > 0)。这意味着该样本的权重被减小。
    • 对于分类错误的样本:yi⋅gk(xi)=−1y_i \cdot g_k(x_i) = -1,则 exp⁡(αk)\exp(\alpha_k) 是一个大于1的数。这意味着该样本的权重被增大。
    • 归一化因子 ZkZ_k 保证了所有权重更新后仍然构成一个概率分布。讲师举了个小例子:若某两个样本更新后分别是 0.3 和 0.2,除以 Zk=0.5Z_k = 0.5 后就是 0.60.6 和 0.40.4——每一步的权重和恒为 1。

3. 组合最终强分类器

经过 KK 轮迭代后,我们得到了 KK 个弱分类器及其权重 {gk(x),αk}k=1K\lbrace g_k(x), \alpha_k\rbrace _{k=1}^K。最终的强分类器 G(x)G(x) 是它们的加权投票结果: G(x)=sign(∑k=1Kαkgk(x))G(x) = \text{sign}\left( \sum_{k=1}^{K} \alpha_k g_k(x) \right) 即,将所有弱分类器的预测结果乘以其权重后求和,然后取符号。结果为正则预测为 +1+1,为负则预测为 −1-1。

AdaBoost工作机制可视化与代码实现

为了直观理解样本权重调整如何工作,我们设想一个简单的二维分类问题。下图(概念示意)展示了AdaBoost的三轮迭代过程:

  1. 第一轮:初始权重均匀(所有点大小相同)。弱分类器1(一条分割线)将一些红点和蓝点分错。算法增加这些错分点的权重(图中点变大)。
  2. 第二轮:由于错分点权重变大,弱分类器2会努力去正确分类这些“重点关注”的点,从而产生一条不同的分割线。它纠正了部分第一轮的错分点,但又可能分错其他点。算法再次更新权重,增大新一轮的错分点权重。
  3. 第三轮:弱分类器3继续聚焦于当前权重大的(即之前难以分类的)点。
  4. 最终组合:将三个弱分类器的决策边界(及其权重)结合起来,通过加权投票,形成了一个复杂且分类能力更强的边界,能够很好地分离所有点。

关键洞察:Boosting不是选择最后一个最好的分类器,而是将所有弱分类器的智慧(以不同权重)结合起来。每个分类器只擅长处理一部分问题,但通过聚焦错误和加权组合,它们共同解决了整个难题。

下面,我们通过一个极简化的数值例子,用代码实现AdaBoost的一轮核心计算,以验证公式。

import math

# ===== AdaBoost 单轮核心计算示例 =====
# 注意:这是一个自包含的演示块,展示公式计算,并非完整训练循环。

# 1. 模拟数据:4个样本,真实标签为+1或-1
y_true = [1, 1, -1, -1]  # 真实标签

# 2. 模拟第k轮的状态
# 假设当前样本权重 w_k (已经归一化,和为1)
w_k = [0.25, 0.25, 0.25, 0.25]
# 假设弱分类器 g_k 对4个样本的预测结果
g_pred = [1, -1, -1, 1]  # 第二个和第四个样本预测错误

# 3. 计算误差率 e_k: 错分样本的权重和
e_k = 0.0
for i in range(len(y_true)):
    if g_pred[i] != y_true[i]:
        e_k += w_k[i]
print(f"当前样本权重: {w_k}")
print(f"弱分类器预测: {g_pred}")
print(f"误差率 e_k = {e_k:.4f}")

# 4. 计算弱分类器权重 alpha_k (加入平滑防止除零或log(0))
def compute_alpha(epsilon, eps=1e-10):
    epsilon = max(min(epsilon, 1 - eps), eps)  # 限制在[eps, 1-eps]区间
    return 0.5 * math.log((1 - epsilon) / epsilon)

alpha_k = compute_alpha(e_k)
print(f"弱分类器权重 alpha_k = {alpha_k:.4f}")

# 5. 更新样本权重 w_{k+1,i}
w_new_numerator = []  # 更新权重的分子部分
for i in range(len(y_true)):
    # 计算 y_i * g_k(x_i)
    product = y_true[i] * g_pred[i]  # 正确时为+1,错误时为-1
    # 计算分子: w_k[i] * exp(-alpha_k * product)
    # 对指数项进行限幅,防止数值溢出(虽然本例很小,但养成好习惯)
    exponent = -alpha_k * product
    exponent = max(min(exponent, 500), -500)  # 限制在[-500, 500]区间
    w_new_numerator.append(w_k[i] * math.exp(exponent))

# 6. 计算归一化因子 Z_k
Z_k = sum(w_new_numerator)
print(f"归一化因子 Z_k = {Z_k:.4f}")

# 7. 得到归一化后的新权重 w_{k+1}
w_kplus1 = [num / Z_k for num in w_new_numerator]
print(f"更新后样本权重 w_{{k+1}}: {[round(w, 4) for w in w_kplus1]}")
print(f"验证权重和: {sum(w_kplus1):.4f}")
当前样本权重: [0.25, 0.25, 0.25, 0.25]
弱分类器预测: [1, -1, -1, 1]
误差率 e_k = 0.5000
弱分类器权重 alpha_k = 0.0000
归一化因子 Z_k = 1.0000
更新后样本权重 w_{k+1}: [0.25, 0.25, 0.25, 0.25]
验证权重和: 1.0000

在这个特例中,误差率 ek=0.5e_k=0.5(随机猜测),因此计算出的 αk=0\alpha_k=0。根据更新公式,exp(−0∗±1)=1exp(-0 * \pm1) = 1,所以样本权重没有发生变化。这符合预期:一个表现不优于随机猜测的分类器,不应该影响样本的权重分布,也不会在最终投票中拥有话语权。

Boosting的优势、局限与变种

优势:

  1. 精度高:通过聚焦错误,能构建出非常强大的模型。
  2. 灵活:几乎可以集成任何类型的弱学习器——决策树、朴素贝叶斯都可以(本课程聚焦的弱学习器是决策树)。

局限与注意事项:

  1. 对噪声数据和异常值敏感:Bagging 的放回式采样天然会”稀释”极端噪声点的影响,而 Boosting 反其道而行——它持续加大错分样本的权重,如果这些样本本身是噪声,后续的学习器就会被”带偏”。这也是 Bagging 降方差、Boosting 降偏差的根源之一。
  2. 训练速度慢:因为必须一个分类器接一个分类器地顺序训练,无法像 Bagging 那样把各棵树扔到不同机器上并行。
  3. 要求弱学习器:弱学习器需要至少比瞎猜略好(ek<0.5e_k < 0.5),否则会被”开除”。

变种:本节的算法叫 AdaBoost——Adaptive Boosting,“自适应”指的就是样本权重随每轮错误动态调整。Boosting 家族还有更通用的 Gradient Boosting(把提升看作函数空间的梯度下降),它与决策树结合就是 GBDT——这正是下一节的主角。

📝 动手练一练

  1. 概念辨析:假设在一个二分类AdaBoost的中期迭代中,某个弱分类器 gt(x)g_t(x) 在当前样本权重分布下的误差率 et=0.1e_t = 0.1。请计算它的权重 αt\alpha_t。如果下一个弱分类器 gt+1(x)g_{t+1}(x) 的误差率 et+1=0.4e_{t+1} = 0.4,谁的“话语权”更大?这说明了Boosting的什么倾向?
👉 点击查看参考答案

计算 αt\alpha_t: αt=12ln⁡(1−0.10.1)=12ln⁡(9)≈12×2.1972≈1.0986\alpha_t = \frac{1}{2} \ln\left(\frac{1 - 0.1}{0.1}\right) = \frac{1}{2} \ln(9) \approx \frac{1}{2} \times 2.1972 \approx 1.0986

计算 αt+1\alpha_{t+1}: αt+1=12ln⁡(1−0.40.4)=12ln⁡(1.5)≈12×0.4055≈0.2027\alpha_{t+1} = \frac{1}{2} \ln\left(\frac{1 - 0.4}{0.4}\right) = \frac{1}{2} \ln(1.5) \approx \frac{1}{2} \times 0.4055 \approx 0.2027

比较:αt(1.0986)>αt+1(0.2027)\alpha_t (1.0986) > \alpha_{t+1} (0.2027)。

说明:误差率更小(性能更好)的弱分类器 gt(x)g_t(x) 获得了更大的权重。这体现了Boosting的核心倾向:给予更准确的弱分类器更高的投票权重,让它们在最终决策中发挥更重要的作用。整个集成模型的质量依赖于一系列“小而精”的弱分类器,而不是少数几个“强”但可能过拟合的分类器。

  1. 代码思考:观察上面代码演示的输出,当 ek=0.5e_k=0.5 时,αk=0\alpha_k=0,样本权重未更新。请你想一想,如果我们要修改代码,模拟一个 ek=0.2e_k=0.2 的情况(即弱分类器较好),应该改变哪个变量?改变后,被分错的样本权重是会增大还是减小?请尝试在脑海中或草稿上推算一下。
👉 点击查看参考答案

要模拟 ek=0.2e_k=0.2,就要让”错分样本的权重和”等于 0.2。改两个变量即可:设初始权重 w_k = [0.3, 0.25, 0.25, 0.2],弱分类器预测 g_pred = [1, 1, -1, 1]——只有第 4 个样本被分错,误差率 ek=0.2e_k = 0.2。

此时 αk=12ln⁡0.80.2=12ln⁡4=ln⁡2≈0.6931\alpha_k = \frac{1}{2}\ln\frac{0.8}{0.2} = \frac{1}{2}\ln 4 = \ln 2 \approx 0.6931,于是放大/缩小因子恰好是干净的两档:

  • 分错的样本 4:乘 eαk=2e^{\alpha_k} = 2,权重 0.2→0.40.2 \to 0.4(增大)
  • 分对的样本 1、2、3:乘 e−αk=0.5e^{-\alpha_k} = 0.5,权重 0.3→0.150.3 \to 0.15、0.25→0.1250.25 \to 0.125、0.25→0.1250.25 \to 0.125(减小)

归一化因子 Zk=0.4+0.15+0.125+0.125=0.8Z_k = 0.4 + 0.15 + 0.125 + 0.125 = 0.8,更新后权重为 [0.1875, 0.15625, 0.15625, 0.5][0.1875,\ 0.15625,\ 0.15625,\ 0.5]——错分样本的权重从 0.2 一跃成为 0.5,下一轮弱分类器必然重点照顾它。这正是 AdaBoost 的思想:加错减对,让集成越学越准。

本章小结

本节我们深入探讨了集成学习的另一大支柱——Boosting,并重点剖析了其代表算法AdaBoost。我们理解了其与Bagging在并行/串行、聚焦方差/偏差上的根本区别。通过拆解AdaBoost的算法步骤,我们掌握了其双重权重(样本权重、分类器权重)的自适应更新机制,并理解了这种机制如何通过让后续分类器不断修正前序错误,从而组合成一个强大的模型。

📋 行动清单

  • 理清流程:尝试在不看讲义的情况下,在白板上画出AdaBoost一轮迭代的计算流程图,包括输入、输出和关键公式。
  • 手动计算:找一个小数据集(3-4个样本),手动模拟AdaBoost的前两轮迭代,计算每一步的 eke_k, αk\alpha_k 和更新后的样本权重,加深对公式的理解。
  • 拓展阅读:了解Boosting家族的其他成员,如Gradient Boosting的核心思想(用梯度下降的角度理解提升过程),为学习GBDT、XGBoost等高级主题打下基础。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 第7章课件:经典机器学习模型 III(CART/集成)
    下载
  • 第7章笔记:CART 树
    下载
  • 第7章笔记:集成学习
    下载
  • 第7章笔记:GBDT
    下载
  • 第7章代码包(RandomForest)
    下载