一、集成学习概述
集成学习(ensemble learning)通过构建并结合多个个体学习器来完成学习任务,核心思想是 "集众家之长"------ 就像多个专家共同判断往往比单个专家更可靠。其关键在于如何生成多样化的个体学习器并设计有效的结合策略。
结合策略
- 简单平均法:对多个学习器的输出取平均值(适用于回归任务)。
- 加权平均法:为不同学习器分配不同权重,权重之和为 1,更信任性能好的学习器。
- 投票法:"少数服从多数",适用于分类任务,多个学习器投票决定最终类别。
二、集成算法分类
根据个体学习器的生成方式,集成算法可分为三类:
算法类型 | 特点 | 代表算法 |
---|---|---|
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 流程 :
- 初始化样本权重(所有样本权重相同);
- 训练弱分类器,分错的样本权重提高,分对的降低;
- 重复训练新分类器,聚焦前一轮的错误样本;
- 最终结合所有弱分类器,性能好的分类器权重更高。
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}")
代码说明
- 数据集 :
load_wine()
包含 178 个样本,13 个特征(如酒精含量、苹果酸等),分为 3 类葡萄酒。 - 模型参数:使用 100 棵决策树,启用袋外数据评估,确保结果可靠。
- 评估指标:通过准确率和分类报告判断模型性能,随机森林在该数据集上通常能达到 95% 以上的准确率。
- 特征重要性:随机森林可输出各特征对分类的贡献度,例如 "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 的迭代次数)进一步优化性能。