43·监督学习-分类进阶

集成学习概述:Bagging 与 Boosting

ensembletheory

第43课 - 集成学习概述:Bagging 与 Boosting

1. 学习目标

完成本课学习后,你将能够:

  • 理解集成学习的核心思想:明白为什么“三个臭皮匠,顶个诸葛亮”在机器学习中同样适用。
  • 清晰区分Bagging与Boosting:掌握两种主流集成策略的工作原理、核心区别及各自优势。
  • 使用Scikit-learn实现基础的Bagging和Boosting模型:重点掌握随机森林和AdaBoost分类器的应用。
  • 评估集成模型的性能:对比单一模型与集成模型在分类任务上的表现。
  • 了解集成模型的适用场景:知道在什么情况下应优先考虑使用Bagging或Boosting。

2. 核心概念

想象一下,你要对一道复杂的数学题给出答案。如果只问一个人,你得到的可能是对是错。但如果你问一个班级的50个同学,然后选择出现次数最多的答案,这个答案正确的概率是不是大大提高了?这就是集成学习的核心思想:将多个“弱学习器”组合成一个“强学习器”,以获得比任何单个学习器都更好的预测性能和稳定性。

集成学习主要分为两大流派:BaggingBoosting

Bagging (Bootstrap Aggregating) - “民主投票”

  • 核心并行训练,降低方差
  • 工作方式
    1. 自助采样:从原始数据集中,通过有放回的随机抽样,生成多个大小相同的子数据集。
    2. 独立训练:在每个子数据集上独立训练一个基学习器(通常是同质的,比如都是决策树)。
    3. 聚合结果:对于分类任务,采用“多数投票”;对于回归任务,采用“平均值”。
  • 代表算法随机森林。它在Bagging的基础上,还引入了特征随机选择,即在每棵决策树的每个节点进行分裂时,只从随机选取的部分特征中找最佳划分,进一步增加了多样性,降低了模型之间的相关性。
  • 优势:能有效减少过拟合,提高模型稳定性,对数据中的噪声不敏感。

Boosting - “接力纠错”

  • 核心串行训练,降低偏差
  • 工作方式
    1. 顺序训练:基学习器被顺序创建。
    2. 关注错误:每个后续的学习器都更加关注前一个学习器预测错误的样本。通常通过调整样本权重(给错误样本更高权重)或拟合前序模型的残差来实现。
    3. 加权组合:所有学习器根据其准确性进行加权组合,通常准确率高的学习器拥有更大的话语权。
  • 代表算法AdaBoost, Gradient Boosting, XGBoost, LightGBM
  • 优势:能将多个非常简单的模型(如决策树桩)组合成一个非常强大的模型,显著减少偏差,通常能获得比单一模型更高的准确率。

简单比喻

  • Bagging 就像班级集体投票决定一个方案,每个人的意见独立,最后取共识。它稳定,不易受个别“极端”同学影响。
  • Boosting 就像组建一个专家小组,每个人研究前一个人的错误报告,并专门攻克难题。它强力,但可能对某些“疑难杂症”过于敏感。

3. 代码示例

我们将使用Scikit-learn的make_moons数据集生成一些非线性可分的数据,分别用单一决策树、Bagging(随机森林)和Boosting(AdaBoost)进行分类,并对比它们的效果。

# 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier
from sklearn.metrics import accuracy_score, classification_report

# 1. 生成和准备数据
X, y = make_moons(n_samples=500, noise=0.3, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 2. 定义三个模型
# 单一决策树(基学习器)
dt_clf = DecisionTreeClassifier(random_state=42)
# Bagging代表:随机森林(100棵树)
rf_clf = RandomForestClassifier(n_estimators=100, random_state=42)
# Boosting代表:AdaBoost(以决策树桩为基学习器)
ada_clf = AdaBoostClassifier(n_estimators=100, random_state=42) # 默认基学习器是决策树桩(max_depth=1)

# 3. 训练模型并评估
models = [dt_clf, rf_clf, ada_clf]
model_names = ["单一决策树", "随机森林(Bagging)", "AdaBoost(Boosting)"]

for model, name in zip(models, model_names):
    # 训练
    model.fit(X_train, y_train)
    # 预测
    y_pred = model.predict(X_test)
    # 评估
    accuracy = accuracy_score(y_test, y_pred)
    print(f"模型: {name}")
    print(f"测试集准确率: {accuracy:.4f}")
    print("-" * 50)

# 4. 可视化决策边界(以随机森林为例)
def plot_decision_boundary(model, X, y, ax, title):
    # 设置坐标轴范围和网格
    h = 0.02
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))
    
    # 预测网格中每个点的类别
    Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    
    # 绘制决策边界和数据点
    ax.contourf(xx, yy, Z, alpha=0.8, cmap=plt.cm.RdYlBu)
    ax.scatter(X[:, 0], X[:, 1], c=y, s=20, edgecolor='k', cmap=plt.cm.RdYlBu)
    ax.set_title(title)
    ax.set_xlabel('Feature 1')
    ax.set_ylabel('Feature 2')

fig, axes = plt.subplots(1, 3, figsize=(18, 5))
for model, name, ax in zip(models, model_names, axes):
    plot_decision_boundary(model, X_test, y_test, ax, name)
plt.tight_layout()
plt.show()

运行结果预期

  • 你会看到三个模型在测试集上的准确率打印出来。通常,随机森林AdaBoost的准确率会高于单一决策树,且随机森林的决策边界可能更平滑,AdaBoost则可能更专注于拟合某些复杂区域。
  • 可视化图会展示三个模型在测试集上的决策边界,直观地看到集成模型如何获得更合理、更复杂的边界。

4. 实践练习

练习1(基础): 基分类器对Bagging的影响

  • 任务:修改上面的代码,尝试将RandomForestClassifier的基学习器(base_estimator)从默认的决策树改为KNeighborsClassifier(k=1)。观察并解释性能变化。
  • 要求:打印使用KNN作为基分类器的Bagging模型和单独一个KNN模型的准确率。

练习2(进阶): Boosting的迭代效应

  • 任务:创建一个AdaBoostClassifier,设置n_estimators=5,并将其estimators_(训练好的基学习器列表)打印出来。然后,分别用第1个基学习器、前3个基学习器组合、以及全部5个基学习器组合进行预测,观察随着迭代次数增加,准确率如何变化。
  • 提示:你需要手动模拟预测过程,因为模型没有直接提供中间步骤的预测接口。

练习3(分析): 解释你的发现

  • 任务:基于练习1和练习2的观察,用一两句话回答:为什么随机森林通常比单一决策树表现好?为什么AdaBoost随着迭代增加,训练集准确率通常会升高?

5. 常见错误

  1. 混淆方差与偏差:错误地认为Bagging和Boosting解决的是同一个问题。记住:Bagging主攻方差(过拟合),Boosting主攻偏差(欠拟合)。在数据噪声很大时,Boosting(尤其是梯度提升)可能更容易过拟合。
  2. 忽略数据预处理:虽然树模型对数据缩放不敏感,但集成模型并非对所有预处理免疫。对于基于梯度提升的方法,异常值可能影响较大。
  3. 参数调优不足:直接使用默认参数。例如,随机森林的n_estimators(树的数量)和max_features(每次分裂考虑的特征数),AdaBoost的learning_rate(学习率)和base_estimator的复杂度都需要根据数据调整。
  4. 期望过高:集成学习是“锦上添花”,而不是“无中生有”。如果基学习器太差,或者数据特征毫无信息量,集成模型也无能为力。

6. 小结

本课我们走进了集成学习的大门,重点认识了其两大核心流派:

  • Bagging:通过自助采样和并行投票来降低模型的方差,代表是随机森林。它像是一个稳定的“委员会决策”系统。
  • Boosting:通过顺序训练和关注错误来降低模型的偏差,代表是AdaBoost。它像一个不断“迭代改进”的专家团队。

集成学习是构建高性能机器学习模型的基石。理解其思想,将为你后续学习更强大的算法(如梯度提升树、XGBoost)打下坚实基础。下一课,我们将深入剖析AdaBoost算法的具体数学原理和实现细节。

练习编辑器

rust
Loading...

继续学习

完成本课后,建议继续学习下一课「AdaBoost 算法」 以巩固所学知识。