机器学习之集成算法学习

一、集成学习概述

集成学习(ensemble learning)通过构建并结合多个个体学习器来完成学习任务,核心思想是 "集众家之长"------ 就像多个专家共同判断往往比单个专家更可靠。其关键在于如何生成多样化的个体学习器并设计有效的结合策略。

结合策略

  1. 简单平均法:对多个学习器的输出取平均值(适用于回归任务)。
  2. 加权平均法:为不同学习器分配不同权重,权重之和为 1,更信任性能好的学习器。
  3. 投票法:"少数服从多数",适用于分类任务,多个学习器投票决定最终类别。

二、集成算法分类

根据个体学习器的生成方式,集成算法可分为三类:

算法类型 特点 代表算法
Bagging 个体学习器并行生成,无强依赖关系 随机森林
Boosting 个体学习器串行生成,后一个依赖前一个 AdaBoost
Stacking 分阶段集成,第一阶段用多种学习器生成结果,第二阶段用这些结果训练新模型 多模型堆叠

三、典型集成算法详解

1. Bagging 与随机森林

  • Bagging 原理:通过 bootstrap 抽样(有放回采样)生成多个不同的训练集,并行训练多个分类器,最终用投票法(分类)或平均法(回归)结合结果。

  • 随机森林:在 Bagging 基础上增加 "双重随机性":

    • 数据采样随机(bootstrap);
    • 特征选择随机(每个决策树仅用部分特征训练)。
  • 随机森林优势

    • 处理高维数据无需特征选择;
    • 可评估特征重要性;
    • 并行化训练,速度快;
    • 结果易可视化分析。
  • 核心参数RandomForestClassifier):

    • n_estimators:树的数量(默认 100);
    • oob_score:是否用袋外数据评估(默认 False,True 时等效交叉验证);
    • bootstrap:是否有放回采样(默认 True)。

2. Boosting 与 AdaBoost

  • Boosting 原理:串行生成学习器,后一个学习器会针对前一个的错误进行优化,通过加权调整样本和学习器的重要性。
  • AdaBoost 流程
    1. 初始化样本权重(所有样本权重相同);
    2. 训练弱分类器,分错的样本权重提高,分对的降低;
    3. 重复训练新分类器,聚焦前一轮的错误样本;
    4. 最终结合所有弱分类器,性能好的分类器权重更高。

3. Stacking

  • 原理 :分阶段集成多种学习器(如 KNN、SVM、随机森林等):
    • 第一阶段:用不同学习器对数据训练,得到各自的预测结果;
    • 第二阶段:将第一阶段的结果作为新特征,训练一个元模型(如逻辑回归),输出最终结果。

四、代码实现:随机森林实现葡萄酒分类

以葡萄酒数据集为例,用随机森林完成分类任务:

python

运行

复制代码
# 导入必要的库
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report

# 1. 加载数据集
wine = load_wine()
X = wine.data  # 特征数据(13个特征,如酒精含量、苹果酸等)
y = wine.target  # 标签(3种葡萄酒类别)
print("特征名称:", wine.feature_names)
print("样本数量:", X.shape[0], ",类别数量:", len(set(y)))

# 2. 划分训练集和测试集(7:3)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42  # 固定随机种子,保证结果可复现
)

# 3. 初始化随机森林模型
rf = RandomForestClassifier(
    n_estimators=100,  # 100棵决策树
    oob_score=True,    # 用袋外数据评估模型
    bootstrap=True,    # 启用有放回采样
    random_state=42
)

# 4. 训练模型
rf.fit(X_train, y_train)

# 5. 模型评估
# 预测测试集
y_pred = rf.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"\n测试集准确率:{accuracy:.4f}")

# 详细分类报告(精确率、召回率、F1值)
print("\n分类报告:")
print(classification_report(y_test, y_pred, target_names=[f"类别{i}" for i in range(3)]))

# 查看特征重要性
feature_importance = dict(zip(wine.feature_names, rf.feature_importances_))
print("\n特征重要性:")
for feature, importance in sorted(feature_importance.items(), key=lambda x: x[1], reverse=True):
    print(f"{feature}: {importance:.4f}")

代码说明

  1. 数据集load_wine()包含 178 个样本,13 个特征(如酒精含量、苹果酸等),分为 3 类葡萄酒。
  2. 模型参数:使用 100 棵决策树,启用袋外数据评估,确保结果可靠。
  3. 评估指标:通过准确率和分类报告判断模型性能,随机森林在该数据集上通常能达到 95% 以上的准确率。
  4. 特征重要性:随机森林可输出各特征对分类的贡献度,例如 "proline(脯氨酸)" 通常是区分葡萄酒类别的重要特征。

我还自己尝试了以下乳腺癌案例

导入必要的库

from sklearn.datasets import load_breast_cancer

from sklearn.ensemble import RandomForestClassifier

from sklearn.model_selection import train_test_split

from sklearn.metrics import confusion_matrix, accuracy_score, classification_report

加载并查看数据集信息

cancer = load_breast_cancer()

X = cancer.data # 特征数据(30个特征,如肿瘤半径、纹理等)

y = cancer.target # 标签(0=恶性,1=良性)

打印数据集基本信息

print("数据集信息:")

print(f"特征数量:{X.shape[1]}(特征名称:{', '.join(cancer.feature_names[:5])}...)")

print(f"样本数量:{X.shape[0]}(其中良性样本:{sum(y)},恶性样本:{len(y)-sum(y)})")

划分训练集和测试集(7:3)

X_train, X_test, y_train, y_test = train_test_split(

X, y, test_size=0.3, random_state=42 # 固定随机种子,保证结果可复现

)

初始化随机森林模型并设置参数

rf_cancer = RandomForestClassifier(

n_estimators=150, # 决策树数量(增加树数量可提升稳定性)

max_depth=8, # 限制树深度,防止过拟合

oob_score=True, # 使用袋外数据评估模型性能

bootstrap=True, # 启用有放回抽样(Bagging核心机制)

random_state=42 # 固定随机种子,确保结果一致

)

训练模型

rf_cancer.fit(X_train, y_train)

print(f"\n袋外数据评估准确率:{rf_cancer.oob_score_:.4f}") # 输出袋外得分

模型评估

预测测试集结果

y_pred = rf_cancer.predict(X_test)

计算准确率

accuracy = accuracy_score(y_test, y_pred)

print(f"\n测试集准确率:{accuracy:.4f}")

打印混淆矩阵(直观展示分类错误情况)

print("\n混淆矩阵(行=真实标签,列=预测标签):")

print("(0=恶性,1=良性)")

print(confusion_matrix(y_test, y_pred))

详细分类报告(包含精确率、召回率、F1值)

print("\n分类报告:")

print(classification_report(

y_test, y_pred,

target_names=["恶性肿瘤", "良性肿瘤"] # 为标签添加中文说明

))

特征重要性分析(前10名)

print("\nTop 10 重要特征(对肿瘤分类的贡献度):")

按重要性排序并取前10

top_features = sorted(

zip(cancer.feature_names, rf_cancer.feature_importances_),

key=lambda x: x[1], reverse=True

)[:10]

格式化输出

for i, (name, imp) in enumerate(top_features, 1):

print(f"{i}. {name}: {imp:.4f}({imp*100:.2f}%)")

五、学习总结

集成学习通过组合多个学习器有效提升了模型性能,其中:

  • 随机森林适合处理高维数据,训练高效且结果稳定,是工业界常用的 "万能模型";
  • AdaBoost 专注于修正错误样本,适合处理非线性问题,但对噪声较敏感;
  • Stacking 灵活性高,可融合多种模型的优势,但实现较复杂。

在实际应用中,需根据数据特点选择合适的集成策略,并通过调参(如随机森林的树数量、AdaBoost 的迭代次数)进一步优化性能。