机器学习 Day12 集成学习简单介绍

1.集成学习概述

1.1. 什么是集成学习

集成学习是一种通过组合多个模型来提高预测性能的机器学习方法。它类似于:

  • 超级个体 vs 弱者联盟

    • 单个复杂模型(如9次多项式函数)可能能力过强但容易过拟合

    • 组合多个简单模型(如一堆1次函数)可以增强能力而不易过拟合

集成学习通过生成多个分类器/模型,将它们的预测结果组合起来,通常能获得优于任何单一分类器的预测性能。

1.2. 机器学习的两个核心任务

  1. 如何优化训练数据 - 主要用于解决欠拟合问题------booting

  2. 如何提升泛化性能 - 主要用于解决过拟合问题------bagging

1.3. 集成学习的两种主要方法

Boosting方法

  • 逐步增强学习

  • 通过序列化方式构建模型,每个新模型都更关注前序模型处理不好的样本(错误数据增强)

  • 典型算法:AdaBoost, Gradient Boosting, XGBoost

Bagging方法

  • 采样学习集成

  • 通过并行方式构建多个模型,每个模型基于数据的随机子集

  • 典型算法:随机森林

集成学习的关键优势是:只要单分类器的表现不太差,集成后的结果通常优于单分类器。这种方法能有效平衡模型的偏差和方差,提高泛化能力

2.Bagging和随机森林

2.1Bagging集成原理

先看一个图

2.1.1. Bagging 基本概念

BaggingBootstrap Aggregating ,自助聚合)是一种并行式集成学习方法,通过构建多个相互独立的基学习器,并综合它们的预测结果来提高模型的泛化能力。

核心思想

  • Bootstrap(自助采样) :从训练数据中有放回地随机抽取多个子集,每个子集用于训练一个基学习器。

  • Aggregating(聚合) :所有基学习器的预测结果通过**投票(分类)或平均(回归)**进行集成,得到最终预测。

📌 关键特点

  • 适用于高方差、低偏差的模型(如决策树、神经网络)。

  • 能有效降低方差,减少过拟合风险。(可以理解因为你随机选取数据)


2.1.2. Bagging 算法流程

  1. 自助采样(Bootstrap Sampling)

    • 从原始训练集 DD 中有放回地随机抽取 mm 个样本,构成一个子集 DiDi​。

    • 重复该过程 TT 次,得到 TT 个不同的训练子集。

  2. 基学习器训练

    • 每个子集 DiDi​ 训练一个基学习器(如决策树)。

    • 基学习器之间相互独立(可并行训练)。

  3. 集成预测

    • 分类任务 :采用投票法(多数表决)

    • 回归任务 :采用平均法(取均值)


2.1.3. Bagging 的典型算法:随机森林(Random Forest)

  • 改进点 :不仅对样本进行自助采样,还对特征进行随机选择(进一步降低相关性)。

  • 优势

    • 比普通 Bagging 更鲁棒,抗过拟合能力更强。

    • 能处理高维数据,适用于分类和回归任务。


2.1.4. Bagging 的优缺点

✅ 优点

  • 有效减少方差,防止过拟合。

  • 适用于高噪声数据,鲁棒性强。

  • 可并行训练,计算效率高。

❌ 缺点

  • 低偏差、高方差的模型(如线性回归)提升有限。

  • 如果基学习器本身偏差较大,Bagging 可能无法显著提升性能。

2.2随机森林

2.2.1. 随机森林的核心概念

随机森林是一种基于 Bagging + 决策树(基学习器是决策树) 的集成学习方法,通过构建多棵决策树并综合它们的预测结果来提高模型的泛化能力。

2.2.2核心特点:

双重随机性:样本随机(自助采样),特征随机(随机选择部分特征)

投票机制:分类任务:众数投票(多数表决),回归任务:均值预测

2.2.3构造过程:

2.2.4关键问题解答

Q1:为什么要随机抽样训练集?

  • 如果所有树使用相同的训练数据,会导致所有树高度相似,失去集成的意义。

  • 随机抽样 保证每棵树学习到数据的不同方面,提高多样性。

Q2:为什么要有放回地抽样?

  • 无放回抽样会导致每棵树的训练数据完全不同,可能引入偏差。

  • 有放回抽样 使不同树的数据分布相似但不相同,平衡偏差与方差。

2.3包外估计(之前讲的自助法)

  1. 实际应用示例

(1)随机森林的 OOB 误差计算

python 复制代码
from sklearn.ensemble import RandomForestClassifier

# 启用 OOB 估计
model = RandomForestClassifier(n_estimators=100, oob_score=True)
model.fit(X_train, y_train)

# 输出 OOB 准确率
print("OOB Score:", model.oob_score_)

(2)特征重要性可视化

python 复制代码
import matplotlib.pyplot as plt

# 获取特征重要性
importances = model.feature_importances_

# 可视化
plt.barh(range(X.shape[1]), importances)
plt.yticks(range(X.shape[1]), X.columns)
plt.show()
  1. 关键问题

包外数据能完全替代验证集吗?

可以:在随机森林中,OOB 估计已被证明是无偏的。但:对于超参数调优,建议结合交叉验证。

2.4随机森林API和案例

还是和以前一样,先实例化后使用

案例:

python 复制代码
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.datasets import load_breast_cancer  # 示例数据集

# 1. 加载数据(这里使用sklearn自带的乳腺癌数据集作为示例)
data = load_breast_cancer()
X = data.data
y = data.target

# 2. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 3. 初始化随机森林分类器(启用OOB估计)
rf = RandomForestClassifier(oob_score=True, random_state=42)

# 4. 定义超参数网格
param_grid = {
    "n_estimators": [120, 200, 300, 500, 800, 1200],
    "max_depth": [5, 8, 15, 25, 30],
    "max_features": ["sqrt", "log2"]  # 添加特征选择方式
}

# 5. 使用GridSearchCV进行超参数调优
gc = GridSearchCV(
    estimator=rf,
    param_grid=param_grid,
    cv=5,  # 使用5折交叉验证
    n_jobs=-1,  # 使用所有CPU核心
    verbose=2  # 显示详细日志
)

# 6. 训练模型
gc.fit(X_train, y_train)

# 7. 输出最佳参数和模型评估结果
print("\n=== 最佳参数组合 ===")
print(gc.best_params_)

print("\n=== 模型评估 ===")
print(f"测试集准确率: {gc.score(X_test, y_test):.4f}")

# 8. 获取最佳模型并输出OOB得分
best_rf = gc.best_estimator_
print(f"包外估计(OOB)得分: {best_rf.oob_score_:.4f}")

3.通过一个案例,来看一下我们拿到一个数据如何分析:

3.1题目介绍

3.2题目分析:我说一下目前了解到的各个部分

3.1获取数据

数据描述,可视化

3.2数据基本处理:选取特征值(部分特征值无用,比如id),对于类别不平衡数据的处理(过采样和欠采样),缺失值和异常值的处理,分割数据,将标签值转化为数字(这个案例里会讲)只有进行数据的可视化才能看到数据是否平衡,有无异常值等,所以可视化很重要。

3.3特征处理:特征预处理(归一化,标准化),特征提取(字典特征提取,文本特征提取,图像特征提取),将类别特征转换为One-hot编码。

3.4模型训练:实际上涉及到参数调优,如果算力够强使用交叉验证和网格搜索即可,不行的话可以一个一个来,我们这个案例就是。

3.5模型评估

3.3代码实现

获取数据,以及数据描述:

python 复制代码
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.utils import class_weight

# 加载数据
data = pd.read_csv('./data/otto/train.csv')

# 查看数据形状
print(f"数据集形状: {data.shape}")  # (61878, 95)

# 查看数据概览
print(data.describe())

# 可视化类别分布
plt.figure(figsize=(12, 6))
sns.countplot(x='target', data=data)
plt.title('类别分布情况')
plt.xticks(rotation=45)
plt.show()

可以看到标签值是一个不平衡数据,所以需要进行处理。

数据预处理

(1)确定特征值和标签值

python 复制代码
# 首先需要确定特征值\标签值
y = data["target"]
x = data.drop(["id", "target"], axis=1)

(2)类别不平衡问题处理

python 复制代码
# 欠采样获取数据
from imblearn.under_sampling import RandomUnderSampler
rus = RandomUnderSampler(random_state=0)
X_resampled, y_resampled = rus.fit_resample(x, y)

# 图形可视化,查看数据分布
import seaborn as sns
sns.countplot(y_resampled)
plt.show()

看到处理完毕,并且 类别平衡。

(3)标签值的转化

使用转换器即可

python 复制代码
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y_resampled = le.fit_transform(y_resampled)

(4)分割数据

python 复制代码
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X_resampled, y_resampled, test_size=0.2)

特征工程 这个数据全是0-1数据,是被脱敏处理过后的数据,无需再进行处理

模型训练与评估(这里要使用要求的损失函数)

python 复制代码
# 模型训练
rf = RandomForestClassifier(oob_score=True)#使用包外估计
rf.fit(x_train, y_train)

# 模型预测
y_pre = rf.predict(x_test)

# 计算模型准确率
accuracy = rf.score(x_test, y_test)
print(f"模型在测试集上的准确率: {accuracy}")

# 查看袋外分数
oob_score = rf.oob_score_
print(f"模型的包外估计分数: {oob_score}")

按要求评估:

python 复制代码
from sklearn.metrics import log_loss
log_loss(y_test, y_pre, eps=1e-15, normalize=True)
#normalize是将损失进行归一化

但我们会发现这样会报错,因为 这个评估函数要求输入是一堆矩阵,y_test是一个one-hot编码矩阵,后面的也要求是相应的大小。于是我们更改方式:

python 复制代码
from sklearn.preprocessing import OneHotEncoder
one_hot = OneHotEncoder(sparse=False)#不是密集矩阵

y_test1 = one_hot.fit_transform(y_test.reshape(-1, 1))
y_pre1 = one_hot.fit_transform(y_pre.reshape(-1, 1))

对于 y_test.reshape(-1, 1)y_test 原本可能是一维数组,reshape(-1, 1) 将其转换为二维列向量形式,因为 OneHotEncoder 要求输入数据是二维数组。

这样就可以了吗,但是我们可以通过将预测值的那个矩阵替换为概率矩阵,就是每一行代表一个样本,每一列是代表这个样本属于这个类别的概率:这样会降低特别大

python 复制代码
# 改变预测值的输出模式,让输出结果为百分比概率
y_pre_proba = rf.predict_proba(x_test)

# 再次查看袋外分数
oob_score = rf.oob_score_
print(f"模型的袋外分数: {oob_score}")

# 第二次 logloss 模型评估
log_loss_value_2 = log_loss(y_test1, y_pre_proba, eps=1e-15, normalize=True)
print(f"第二次计算的 log_loss 值: {log_loss_value_2}")

参数调优 最好使用网格搜索的方法,当算力小的时候可以如下调优

python 复制代码
# 确定n_estimators的取值范围
tuned_parameters = range(10, 200, 10)
# 创建添加存放accuracy的一个numpy数组
accuracy_t = np.zeros(len(tuned_parameters))
# 创建添加error的一个numpy数组(就是要求的损失函数数组)
error_t = np.zeros(len(tuned_parameters))
# 调优过程实现
for j, one_parameter in enumerate(tuned_parameters):
    rf2 = RandomForestClassifier(n_estimators=one_parameter,
                                 max_depth=10,
                                 max_features=10,
                                 min_samples_leaf=10,
                                 oob_score=True,
                                 random_state=0,
                                 n_jobs=-1)
    rf2.fit(x_train, y_train)
    # 输出accuracy
    accuracy_t[j] = rf2.oob_score_
    # 输出log_loss
    y_pre = rf2.predict_proba(x_test)
    error_t[j] = log_loss(y_test, y_pre, eps=1e-15, normalize=True)
    print(error_t)

# 优化结果过程可视化
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 4), dpi=100)
axes[0].plot(tuned_parameters, error_t)
axes[1].plot(tuned_parameters, accuracy_t)
axes[0].set_xlabel("n_estimators")
axes[0].set_ylabel("error_t")
axes[1].set_xlabel("n_estimators")
axes[1].set_ylabel("accuracy_t")
axes[0].grid(True)
axes[1].grid(True)
plt.show()
python 复制代码
for j, one_parameter in enumerate(tuned_parameters):

相当于给原本的要调优的值加了一个从0开始的索引,方便把每个值存到数组里

注意我们并不是选取数组里最小的作为最优调参,而是通过绘图查看趋势,通常选取趋势平缓的转折点

之后我们固定这个参数,继续进行调优,直到全部调优完毕!

相关推荐
人猿泰飞4 分钟前
【AI训练环境搭建】在Windows11上搭建WSL2+Ubuntu22.04+Tensorflow+GPU机器学习训练环境
windows·ubuntu·机器学习·wsl·gpu训练
量子位11 分钟前
北大团队引领 3D 生成与对齐革新:OctGPT 打破扩散模型垄断
人工智能·gpt·aigc
京东零售技术14 分钟前
生成式 AI 引爆广告效率革命,揭秘京东大模型应用架构的实践之道
人工智能
量子位20 分钟前
华人横扫 ICLR 2025 杰出论文奖,三篇均为华人一作,中科大何向南团队 / 清华姚班北大校友在列
人工智能
量子位20 分钟前
无需数据标注!测试时强化学习,模型数学能力暴增 | 清华 & 上海 AI Lab
人工智能·gitlab·aigc
硅谷秋水23 分钟前
UniOcc:自动驾驶占用预测和预报的统一基准
人工智能·深度学习·机器学习·计算机视觉·自动驾驶
Dm_dotnet25 分钟前
使用CAMEL实现Graph RAG过程记录
人工智能
BuluAI算力云26 分钟前
Second Me重磅升级:全平台Docker部署+OpenAI协议兼容
人工智能
Kenley30 分钟前
MTP(Multi-Token Prediction)
人工智能
链诸葛31 分钟前
Smart AI:在AI浪潮中崛起的智能NFT生态革命者
人工智能