《数据挖掘》学习笔记(十):集成学习
🎯 《数据挖掘》学习笔记(十):集成学习
系列文章目录
| 章节 | 内容 | 状态 |
|---|---|---|
| 第一章 | 绪论 | ✅ |
| 第二章 | 数据描述与统计指标 | ✅ |
| 第三章 | 相关分析 | ✅ |
| 第四章 | 回归分析 | ✅ |
| 第五章 | 数据降维 | ✅ |
| 第六章 | 关联规则挖掘 | ✅ |
| 第七章 | 分类 | ✅ |
| 第八章 | 聚类 | ✅ |
| 第九章 | 异常检测 | ✅ |
| 第十章 | 集成学习 | ✅ |
🔍 第十章 集成学习
10.1 集成学习概述
集成学习的定义: 集成学习是一种通过构建并结合多个学习器来完成学习任务的机器学习技术,其旨在解决单一模型在面对复杂数据预测问题时所遇到的挑战,如噪声干扰、过拟合和欠拟合等。
核心概念:
- 个体学习器(Base Learner):参与集成的单个模型
- 弱学习器(Weak Learner):表现略好于随机猜测的模型
- 强学习器(Strong Learner):由多个弱学习器集成而成的高性能模型
集成学习的优势:
- 提高预测准确率
- 减少过拟合风险
- 提高模型鲁棒性
- 能处理更复杂的问题
10.2 Bagging方法
Bagging(Bootstrap Aggregating)基本原理: Bagging是一族并行化集成学习算法,其一般通过训练多个独立的基学习器,将它们的预测结果进行平均或投票,以得到最优结果。
关键特点:
- 对样本的抽取是有放回的(Bootstrap采样)
- 每个基学习器在不同的数据子集上独立训练
- 通过集成方法降低各子集特定误差对最终模型的影响
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.ensemble import BaggingClassifier, BaggingRegressor
from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score, classification_report, mean_squared_error
from sklearn.datasets import load_iris, load_diabetes
from sklearn.preprocessing import StandardScaler
# 分类示例
iris = load_iris()
X_clf, y_clf = iris.data, iris.target
X_train_clf, X_test_clf, y_train_clf, y_test_clf = train_test_split(
X_clf, y_clf, test_size=0.2, random_state=42
)
# Bagging分类器
bagging_clf = BaggingClassifier(
estimator=DecisionTreeClassifier(max_depth=3),
n_estimators=50,
max_samples=0.8, # 样本采样比例
max_features=0.8, # 特征采样比例
bootstrap=True, # 有放回采样
bootstrap_features=False,
n_jobs=-1,
random_state=42
)
bagging_clf.fit(X_train_clf, y_train_clf)
y_pred_clf = bagging_clf.predict(X_test_clf)
print("Bagging分类器结果:")
print(f"准确率: {accuracy_score(y_test_clf, y_pred_clf):.4f}")
print(f"\n分类报告:\n{classification_report(y_test_clf, y_pred_clf, target_names=iris.target_names)}")
# 对比单个决策树
dt_clf = DecisionTreeClassifier(max_depth=3, random_state=42)
dt_clf.fit(X_train_clf, y_train_clf)
y_pred_dt = dt_clf.predict(X_test_clf)
print(f"\n单个决策树准确率: {accuracy_score(y_test_clf, y_pred_dt):.4f}")
10.3 Boosting方法
Boosting基本原理: Boosting是一族序列化集成学习算法,其根据训练样本集训练出一个基学习器,并根据基学习器的预测表现对训练数据集和基学习器进行调整,直至达到训练轮数。Boosting通过训练一系列基学习器,将它们加权结合成一个泛化性能强的强学习器。
AdaBoost算法:
from sklearn.ensemble import AdaBoostClassifier, AdaBoostRegressor
# AdaBoost分类器
ada_clf = AdaBoostClassifier(
estimator=DecisionTreeClassifier(max_depth=1), # 决策树桩
n_estimators=50,
learning_rate=0.1,
algorithm='SAMME.R',
random_state=42
)
ada_clf.fit(X_train_clf, y_train_clf)
y_pred_ada = ada_clf.predict(X_test_clf)
print("AdaBoost分类器结果:")
print(f"准确率: {accuracy_score(y_test_clf, y_pred_ada):.4f}")
print(f"\n分类报告:\n{classification_report(y_test_clf, y_pred_ada, target_names=iris.target_names)}")
# 查看各基学习器的权重
print(f"\n各基学习器权重: {ada_clf.estimator_weights_[:10]}")
梯度提升树(GBDT):
from sklearn.ensemble import GradientBoostingClassifier, GradientBoostingRegressor
# 回归示例
diabetes = load_diabetes()
X_reg, y_reg = diabetes.data, diabetes.target
X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(
X_reg, y_reg, test_size=0.2, random_state=42
)
# 梯度提升回归器
gbr = GradientBoostingRegressor(
n_estimators=100,
learning_rate=0.1,
max_depth=3,
min_samples_split=5,
subsample=0.8,
random_state=42
)
gbr.fit(X_train_reg, y_train_reg)
y_pred_gbr = gbr.predict(X_test_reg)
print("梯度提升回归器结果:")
print(f"均方误差: {mean_squared_error(y_test_reg, y_pred_gbr):.4f}")
print(f"R²: {gbr.score(X_test_reg, y_test_reg):.4f}")
# 特征重要性
plt.figure(figsize=(10, 6))
importance = pd.Series(gbr.feature_importances_, index=diabetes.feature_names).sort_values(ascending=True)
importance.plot(kind='barh', color='steelblue')
plt.xlabel('重要性')
plt.title('GBDT特征重要性')
plt.show()
10.4 Stacking方法
Stacking基本原理: Stacking是一种集成学习技术,其训练多个基学习器来获得预测结果,并使用这些预测结果训练一个次级学习器,通过次级学习器将多个基学习器的预测结果进行整合,从而得到最终的预测结果。
from sklearn.linear_model import LogisticRegression, LinearRegression
from sklearn.ensemble import StackingClassifier, StackingRegressor
from sklearn.svm import SVC
# Stacking分类器
base_estimators = [
('dt', DecisionTreeClassifier(max_depth=3)),
('svm', SVC(probability=True)),
('logreg', LogisticRegression(max_iter=500))
]
stacking_clf = StackingClassifier(
estimators=base_estimators,
final_estimator=LogisticRegression(max_iter=500),
cv=5,
stack_method='predict_proba',
n_jobs=-1
)
stacking_clf.fit(X_train_clf, y_train_clf)
y_pred_stack = stacking_clf.predict(X_test_clf)
print("Stacking分类器结果:")
print(f"准确率: {accuracy_score(y_test_clf, y_pred_stack):.4f}")
print(f"\n分类报告:\n{classification_report(y_test_clf, y_pred_stack, target_names=iris.target_names)}")
10.5 随机森林
随机森林基本原理: 随机森林是一种通过随机数据采样和随机特征选择的方式构建多个决策树,并利用投票法或平均法将预测结果结合的集成学习算法。
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
# 随机森林分类器
rf_clf = RandomForestClassifier(
n_estimators=100,
max_depth=5,
min_samples_split=5,
max_features='sqrt',
bootstrap=True,
n_jobs=-1,
random_state=42,
oob_score=True # 袋外估计
)
rf_clf.fit(X_train_clf, y_train_clf)
y_pred_rf = rf_clf.predict(X_test_clf)
print("随机森林分类器结果:")
print(f"准确率: {accuracy_score(y_test_clf, y_pred_rf):.4f}")
print(f"袋外得分: {rf_clf.oob_score_:.4f}")
print(f"\n分类报告:\n{classification_report(y_test_clf, y_pred_rf, target_names=iris.target_names)}")
# 特征重要性
plt.figure(figsize=(10, 6))
importance = pd.Series(rf_clf.feature_importances_, index=iris.feature_names).sort_values(ascending=True)
importance.plot(kind='barh', color='steelblue')
plt.xlabel('重要性')
plt.title('随机森林特征重要性')
plt.show()
10.6 XGBoost
XGBoost基本原理: XGBoost是一种提升树模型,基于梯度提升算法框架。它通过不断添加新的树来拟合之前模型的残差,将多个弱学习器进行集成,最终形成一个强学习器。
XGBoost核心特性:
- 正则化:在目标函数中加入正则化项,防止过拟合
- 并行计算:支持特征维度并行
- 缺失值处理:自动处理缺失值
- 剪枝策略:最大深度限制和最小损失增益
- 交叉验证:内置交叉验证功能
import xgboost as xgb
# XGBoost分类器
xgb_clf = xgb.XGBClassifier(
n_estimators=100,
learning_rate=0.1,
max_depth=3,
min_child_weight=1,
subsample=0.8,
colsample_bytree=0.8,
gamma=0,
reg_alpha=0,
reg_lambda=1,
objective='multi:softmax',
eval_metric='mlogloss',
random_state=42,
use_label_encoder=False
)
xgb_clf.fit(
X_train_clf, y_train_clf,
eval_set=[(X_train_clf, y_train_clf), (X_test_clf, y_test_clf)],
verbose=10
)
y_pred_xgb = xgb_clf.predict(X_test_clf)
print("\nXGBoost分类器结果:")
print(f"准确率: {accuracy_score(y_test_clf, y_pred_xgb):.4f}")
print(f"\n分类报告:\n{classification_report(y_test_clf, y_pred_xgb, target_names=iris.target_names)}")
# 训练过程可视化
results = xgb_clf.evals_result()
plt.figure(figsize=(10, 6))
plt.plot(results['validation_0']['mlogloss'], label='训练集')
plt.plot(results['validation_1']['mlogloss'], label='验证集')
plt.xlabel('迭代次数')
plt.ylabel('损失')
plt.title('XGBoost训练过程')
plt.legend()
plt.show()
10.7 LightGBM
LightGBM基本原理: LightGBM同样基于梯度提升框架,通过迭代地训练决策树并将它们组合起来,利用前向分步加法模型,每次在已有模型的基础上添加一个新的弱学习器来纠正之前的错误。
LightGBM核心特性:
- 直方图算法:将连续特征值离散化,加速训练
- Leaf-wise生长策略:选择增益最大的叶子节点分裂
- 数据并行与特征并行:支持多种并行计算方式
- 单边梯度采样:根据梯度大小采样数据
- 互斥特征捆绑:减少特征维度
import lightgbm as lgb
# LightGBM分类器
lgb_clf = lgb.LGBMClassifier(
n_estimators=100,
learning_rate=0.1,
max_depth=3,
num_leaves=15,
min_child_samples=20,
subsample=0.8,
colsample_bytree=0.8,
reg_alpha=0,
reg_lambda=1,
objective='multiclass',
metric='multi_logloss',
random_state=42,
verbose=-1
)
lgb_clf.fit(
X_train_clf, y_train_clf,
eval_set=[(X_train_clf, y_train_clf), (X_test_clf, y_test_clf)],
eval_metric='multi_logloss',
callbacks=[lgb.early_stopping(stopping_rounds=10, verbose=10)],
verbose=10
)
y_pred_lgb = lgb_clf.predict(X_test_clf)
print("\nLightGBM分类器结果:")
print(f"准确率: {accuracy_score(y_test_clf, y_pred_lgb):.4f}")
print(f"\n分类报告:\n{classification_report(y_test_clf, y_pred_lgb, target_names=iris.target_names)}")
# 训练过程可视化
plt.figure(figsize=(10, 6))
lgb.plot_metric(lgb_clf, metric='multi_logloss')
plt.title('LightGBM训练过程')
plt.show()
# 特征重要性
plt.figure(figsize=(10, 6))
lgb.plot_importance(lgb_clf, max_num_features=10)
plt.title('LightGBM特征重要性')
plt.show()
10.8 集成学习算法对比
import time
# 各算法对比
algorithms = {
'Bagging': BaggingClassifier(estimator=DecisionTreeClassifier(max_depth=3), n_estimators=50, random_state=42),
'随机森林': RandomForestClassifier(n_estimators=50, max_depth=5, random_state=42),
'AdaBoost': AdaBoostClassifier(estimator=DecisionTreeClassifier(max_depth=1), n_estimators=50, random_state=42),
'GBDT': GradientBoostingClassifier(n_estimators=50, max_depth=3, random_state=42),
'XGBoost': xgb.XGBClassifier(n_estimators=50, max_depth=3, random_state=42, use_label_encoder=False, eval_metric='mlogloss'),
'LightGBM': lgb.LGBMClassifier(n_estimators=50, max_depth=3, random_state=42, verbose=-1)
}
results = []
print("=" * 80)
print(f"{'算法':<12} {'准确率':<12} {'训练时间(秒)':<15}")
print("=" * 80)
for name, algo in algorithms.items():
start = time.time()
algo.fit(X_train_clf, y_train_clf)
elapsed = time.time() - start
accuracy = accuracy_score(y_test_clf, algo.predict(X_test_clf))
results.append({
'算法': name,
'准确率': accuracy,
'训练时间': elapsed
})
print(f"{name:<12} {accuracy:<12.4f} {elapsed:<15.4f}")
print("=" * 80)
# 可视化对比
results_df = pd.DataFrame(results)
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
axes[0].barh(results_df['算法'], results_df['准确率'], color='steelblue')
axes[0].set_xlabel('准确率')
axes[0].set_title('各算法准确率对比')
axes[0].set_xlim([0.8, 1])
axes[1].barh(results_df['算法'], results_df['训练时间'], color='coral')
axes[1].set_xlabel('训练时间(秒)')
axes[1].set_title('各算法训练时间对比')
plt.tight_layout()
plt.show()
💡 集成学习实战案例
银行危机预测:
# 模拟银行危机预测数据
np.random.seed(42)
n_samples = 1000
bank_data = pd.DataFrame({
'GDP增长率': np.random.normal(3, 2, n_samples),
'失业率': np.random.normal(5, 2, n_samples),
'通货膨胀率': np.random.normal(3, 1.5, n_samples),
'利率': np.random.normal(5, 2, n_samples),
'债务比例': np.random.uniform(0.5, 1.5, n_samples),
'银行储备': np.random.uniform(0.8, 1.2, n_samples)
})
# 生成危机标签
def generate_crisis(row):
risk = 0
if row['GDP增长率'] < 0:
risk += 2
if row['失业率'] > 7:
risk += 2
if row['通货膨胀率'] > 6:
risk += 1
if row['债务比例'] > 1.2:
risk += 1
if row['银行储备'] < 0.9:
risk += 1
return 1 if np.random.random() < risk / 10 else 0
bank_data['危机'] = bank_data.apply(generate_crisis, axis=1)
print(f"银行危机数据:")
print(f"总样本数: {len(bank_data)}")
print(f"危机发生数: {sum(bank_data['危机'])}")
print(f"危机比例: {sum(bank_data['危机'])/len(bank_data)*100:.2f}%")
# 准备数据
X_bank = bank_data.drop('危机', axis=1)
y_bank = bank_data['危机']
X_train_bank, X_test_bank, y_train_bank, y_test_bank = train_test_split(
X_bank, y_bank, test_size=0.2, random_state=42, stratify=y_bank
)
# 使用XGBoost
xgb_bank = xgb.XGBClassifier(
n_estimators=200,
learning_rate=0.05,
max_depth=4,
random_state=42,
use_label_encoder=False,
eval_metric='logloss'
)
xgb_bank.fit(
X_train_bank, y_train_bank,
eval_set=[(X_train_bank, y_train_bank), (X_test_bank, y_test_bank)],
callbacks=[xgb.callback.EarlyStopping(rounds=20, save_best=True)],
verbose=20
)
y_pred_bank = xgb_bank.predict(X_test_bank)
y_prob_bank = xgb_bank.predict_proba(X_test_bank)[:, 1]
print(f"\n银行危机预测结果:")
print(f"准确率: {accuracy_score(y_test_bank, y_pred_bank):.4f}")
print(f"\n分类报告:\n{classification_report(y_test_bank, y_pred_bank, target_names=['无危机', '危机'])}")
# 特征重要性
plt.figure(figsize=(10, 6))
importance = pd.Series(xgb_bank.feature_importances_, index=X_bank.columns).sort_values(ascending=True)
importance.plot(kind='barh', color='steelblue')
plt.xlabel('重要性')
plt.title('银行危机预测 - 特征重要性')
plt.show()
💡 本章小结
本章介绍了各种集成学习方法:
| 方法 | 类型 | 核心思想 | 优势 | 劣势 |
|---|---|---|---|---|
| Bagging | 并行 | 降低方差,提高稳定性 | 计算量大 | 小数据集效果有限 |
| 随机森林 | 并行 | 随机采样+随机特征 | 高效、鲁棒 | 参数较多 |
| AdaBoost | 串行 | 关注错分样本 | 精度高 | 对噪声敏感 |
| GBDT | 串行 | 拟合残差 | 精度高 | 训练慢、过拟合风险 |
| XGBoost | 串行 | 正则化+并行 | 精度高、快 | 参数复杂 |
| LightGBM | 串行 | 直方图+Leaf-wise | 训练极快 | 参数复杂 |
| Stacking | 元学习 | 多层学习器 | 精度高 | 计算量大、复杂 |
🔗 参考资料
- 《数据挖掘》吕欣、王梦宁 著,科学出版社
- GitHub仓库:https://github.com/Feihuo-W/Data-Mining-book-study
- 上一篇:《数据挖掘》学习笔记(九):异常检测
🎉 总结
至此,《数据挖掘》学习笔记系列已全部完成!感谢陪伴与支持!请继续关注FeiHuo的下一个阶段内容吧!期待Ing~~
完整笔记包含:
- ✅ 第一章:绪论
- ✅ 第二章:数据描述与统计指标
- ✅ 第三章:相关分析
- ✅ 第四章:回归分析
- ✅ 第五章:数据降维
- ✅ 第六章:关联规则挖掘
- ✅ 第七章:分类
- ✅ 第八章:聚类
- ✅ 第九章:异常检测
- ✅ 第十章:集成学习
GitHub仓库: https://github.com/Feihuo-W/Data-Mining-book-study
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)