当前位置: 首页 > news >正文

Python数据挖掘之集成技术

文章目录

  • 基本集成技术
    • 一、Bagging(装袋法)
      • 基本思想
      • 主要特点
      • 类比说明
      • 代表算法
      • 一、首先解释这句话的意思
      • 二、Bagging 算法的详细步骤
        • 步骤 1:随机采样(Bootstrap Sampling)
        • 步骤 2:训练多个基分类器
        • 步骤 3:集成预测结果
        • 步骤 4:输出最终结果
      • 三、Bagging 算法伪代码(便于理解)
      • 四、一个生活类比
    • 一、`BaggingClassifier()` 的基本定义
    • 二、参数详细解释(最常用部分)
    • 三、一个实际示例
    • 四、内部原理(工作机制)
    • 五、拓展提示
    • 二、Boosting(提升法)
      • 基本思想
      • 主要特点
      • 类比说明
      • 代表算法
    • 一、核心思想概述
    • 二、提升算法的关键思想:**“关注错的样本”**
      • 工作逻辑:
    • 三、类比理解
    • 四、AdaBoost(Adaptive Boosting)原理简介
      • 算法流程(简化版)
    • 五、一个简单的 Python 示例
    • 六、总结对比
    • 一、AdaBoostClassifier 基本说明
    • 二、主要参数详解
    • 三、简单理解参数作用
    • 四、一个简单的 Python 示例
      • 🧾 运行结果示例(每次略有不同)
    • 🪄 五、总结要点
    • 三、Stacking(堆叠法)
    • 基本思想
    • 类比说明
    • 特点
    • 常见应用
    • 一、Stacking 的核心思想
    • 二、结构特点:两层(有时三层)
      • 第一层:**基分类器(Base Learners)**
      • 第二层:**元分类器(Meta Learner / Meta Model)**
    • 三、工作原理举例(形象版)
    • 四、Stacking 的算法流程
    • 五、一个简单的 Python 示例
      • 输出示例
    • 六、Stacking vs Bagging vs Boosting 对比总结
    • 七、一句话总结
    • **scikit-learn** 中 `StackingClassifier` 的核心构造函数。
    • 一、基本语法
    • 二、参数详细讲解
    • 三、参数关系图解(逻辑)
    • 四、一个完整的示例
    • 五、进一步说明
    • 六、小结对比表
    • 总结对比表
  • 随机森林
    • 一、随机森林的核心思想
    • 二、随机森林的两个“随机”
    • 三、随机森林的训练与预测流程
      • (1)训练阶段:
      • (2)预测阶段:
    • 四、与 Bagging 的关系
    • 五、简单 Python 示例
    • 六、总结一句话记忆法
  • 提升树
    • 二、它为什么叫“提升(Boosting)”?
    • 三、提升树的工作流程(核心思想)
    • 四、为什么叫“梯度提升树(Gradient Boosted Tree)”?
    • 五、与随机森林的区别总结
    • 六、一个简单 Python 例子(GBDT 回归)
    • 七、一句话总结
  • 类不平衡
    • 一、什么是“类不平衡问题”?
    • 二、常见的三类解决思路
      • 1️⃣ 抽样方法(Sampling Methods)
      • 2️⃣ 代价敏感方法(Cost-Sensitive Learning)
      • 3️⃣ 集成学习方法(Ensemble Learning Methods)
    • 📊 三、方法对比总结表
    • 💡 四、小结一句话
    • 一、SMOTE 是什么?
    • 二、它是怎么“合成”新样本的?
      • 主要步骤:
    • 三、SMOTE 的优点与局限
    • 四、Python 实例演示(使用 `imblearn` 库)
      • 运行结果解释
    • 五、总结一句话
    • 一、实验目标
    • 二、完整 Python 示例代码
    • 三、结果示例(输出解释)
    • 四、结果分析
    • 五、小结一句话
    • 一、ADASYN 的核心思想
    • 二、算法步骤概述
    • 三、Python 实例:SMOTE vs ADASYN
    • 四、结果与区别
    • 五、小结一句话
    • 一、实验目标
    • 二、完整 Python 示例代码
    • 三、结果示例(运行后可能略有差异)
    • 四、结果分析
    • 五、对比 SMOTE 的特点
    • 六、小结一句话
    • 一、EasyEnsemble 的核心思想
    • 二、算法原理详解
      • EasyEnsemble 步骤:
    • 三、EasyEnsemble 的优势
    • 四、简单 Python 案例(使用 `imblearn.ensemble.EasyEnsembleClassifier`)
    • 五、运行结果示例
    • 六、小结一句话
  • 案例
    • 一、对比目标
    • 二、完整 Python 实战代码
    • 三、示例结果(可能略有浮动)
      • 【AdaBoost】
      • 【SMOTE + 随机森林】
      • 【EasyEnsemble】
    • 四、结果对比分析
    • 五、总结对比
    • 六、一句话总结

基本集成技术

“集成技术”(Ensemble Learning)确实是数据挖掘与机器学习中的一个重要研究方向。

它的核心思想是:“集思广益”——通过组合多个弱学习器(模型),得到一个性能更强、泛化能力更好的强学习器。

三种主要的集成方法:Bagging、Boosting 和 Stacking


一、Bagging(装袋法)

全称:Bootstrap Aggregating

基本思想

通过自助采样法(Bootstrap Sampling)从训练集中随机抽取多个子集,在每个子集上训练一个独立模型(通常是同类模型,如决策树),最后将这些模型的预测结果进行平均(回归)或投票(分类)
在这里插入图片描述

主要特点

  • 模型之间相互独立
  • 目的是减少方差(variance),从而提高稳定性;
  • 对噪声不敏感;
  • 并行化容易实现。

类比说明

好比老师要判断一个学生的语文水平,不只看一次考试,而是让他考十次不同的卷子(训练不同数据子集),然后取平均成绩(集成结果),结果更客观。

代表算法

👉 随机森林(Random Forest)
它是 Bagging 的代表作:以决策树为基学习器,在每次训练时不仅随机抽样数据,还随机选择特征子集,从而让各树之间更加独立。


当然可以 😊
Bagging(装袋算法) 的核心涉及两个概念:基分类器(base classifier)算法步骤(Bagging 流程)


一、首先解释这句话的意思

“训练的分类器 MkM_kMk 可以是任意的分类模型,例如决策树、KNN等,也称为基分类器(base classifier)。”

这句话的意思是:

  • 在 Bagging 中,我们不是只训练一个模型,而是训练多个模型 M1,M2,…,MkM_1, M_2, \dots, M_kM1,M2,,Mk

  • 这些模型都叫 基分类器(base classifiers),因为它们是整个集成模型的“基础单元”。

  • 每个 MkM_kMk 可以是任意类型的分类算法,比如:

    • 决策树(Decision Tree)
    • K 最近邻(KNN)
    • 逻辑回归(Logistic Regression)
    • 神经网络(Neural Network)等
  • 最后,这些多个分类器的预测结果会被组合起来(投票或平均)形成最终的分类器。

类比理解:
就像一个评委团,每位评委都可以有不同的评判标准(不同算法),但最终结果由他们的投票决定(集成结果)。


二、Bagging 算法的详细步骤

下面是装袋法(Bagging)的具体流程,用更直观的方式解释:

步骤 1:随机采样(Bootstrap Sampling)

从原始训练集 DDD(包含 N 个样本)中,有放回地随机抽取 N 个样本,形成一个新的训练子集 DkD_kDk

  • “有放回”意味着同一个样本可能被抽到多次;
  • 这样我们就得到多个不同的子集:D1,D2,…,DKD_1, D_2, \dots, D_KD1,D2,,DK
步骤 2:训练多个基分类器

对每一个采样得到的子集 DkD_kDk,训练一个基分类器 MkM_kMk
这些分类器通常是相互独立的,因为它们的训练数据不同。

步骤 3:集成预测结果

当有新样本 xxx 要分类时,让每个分类器 MkM_kMk 都给出预测结果:

  • 对分类问题:通过多数投票法决定最终类别;
  • 对回归问题:取所有预测值的平均值
步骤 4:输出最终结果

将上一步的投票/平均结果作为整个 Bagging 模型的最终预测输出。


三、Bagging 算法伪代码(便于理解)

Input: 训练集 D = {(x1, y1), (x2, y2), …, (xN, yN)}
Output: 集成分类器 M*1. For k = 1 to K:从 D 中有放回地随机采样 N 个样本,得到 Dk用 Dk 训练基分类器 Mk
2. 对新的样本 x:对所有 Mk 进行预测,得到 K 个结果分类任务:按多数投票决定最终类别回归任务:取预测值平均
3. 输出最终预测结果

四、一个生活类比

假设你要决定“明天是否会下雨”,你请了 5 位气象专家:

  • 每位专家(基分类器)都用自己掌握的数据(随机抽样数据)预测;
  • 有人认为会下,有人认为不会;
  • 最后你采取少数服从多数的方式作决定;
    这就是 Bagging 的思想:集体智慧,平均偏差。

# 导入必要的库
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.metrics import accuracy_score# 1. 加载数据集
iris = load_iris()
X, y = iris.data, iris.target# 2. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# 3. 训练单个决策树分类器
single_tree = DecisionTreeClassifier(random_state=42)
single_tree.fit(X_train, y_train)
y_pred_single = single_tree.predict(X_test)# 4. 训练Bagging集成分类器(以决策树为基分类器)
bagging = BaggingClassifier(base_estimator=DecisionTreeClassifier(),  # 基分类器n_estimators=10,                          # 子模型数量random_state=42
)
bagging.fit(X_train, y_train)
y_pred_bagging = bagging.predict(X_test)# 5. 输出结果对比
print("单个决策树准确率:", accuracy_score(y_test, y_pred_single))
print("Bagging集成模型准确率:", accuracy_score(y_test, y_pred_bagging))

一、BaggingClassifier() 的基本定义

from sklearn.ensemble import BaggingClassifierbagging = BaggingClassifier(base_estimator=None,n_estimators=10,max_samples=1.0,max_features=1.0,bootstrap=True,bootstrap_features=False,n_jobs=None,random_state=None
)

二、参数详细解释(最常用部分)

参数名含义默认值说明
base_estimator基分类器None指定你想集成的基本模型(例如 DecisionTreeClassifier())。如果为 None,则默认使用决策树。
n_estimators基分类器数量10表示要训练多少个子模型。通常 10~100 效果较好。
max_samples每个子模型采样的样本比例或数量1.0如果是比例(如 0.8),表示从原始数据中随机采样 80% 样本(有放回)。
max_features每个子模型使用的特征比例或数量1.0类似于随机森林中“特征随机性”,可提高多样性。
bootstrap是否对样本进行“有放回采样”TrueTrue 表示使用 Bootstrap(Bagging 的核心思想);False 表示不放回采样。
bootstrap_features是否对特征进行“有放回采样”False通常为 False;若为 True,会在特征上也做随机化。
n_jobs并行计算的线程数None设置为 -1 表示使用全部 CPU 核心加速训练。
random_state随机种子None为保证实验可重复性,可设为固定数值,如 42

三、一个实际示例

from sklearn.datasets import load_iris
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score# 加载数据
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)# 创建 Bagging 模型
bag_model = BaggingClassifier(base_estimator=DecisionTreeClassifier(),  # 基分类器n_estimators=20,                          # 训练 20 个决策树max_samples=0.8,                          # 每个子模型采 80% 的样本bootstrap=True,                           # 有放回采样n_jobs=-1,                                # 并行计算random_state=42
)# 训练与预测
bag_model.fit(X_train, y_train)
y_pred = bag_model.predict(X_test)# 结果
print("准确率:", accuracy_score(y_test, y_pred))

输出示例:

准确率:0.9777

四、内部原理(工作机制)

BaggingClassifier 内部大致做了以下几件事:

  1. 采样阶段:对原始训练集做 n_estimators 次有放回采样,得到多个训练子集。

  2. 训练阶段:在每个子集上训练一个基分类器(base_estimator)。

  3. 预测阶段

    • 分类任务:所有分类器投票,选票最多的类别作为最终预测;
    • 回归任务:取所有预测结果的平均值(对应 BaggingRegressor)。

五、拓展提示

  • BaggingClassifier 是通用装袋算法;
  • 若你指定的 base_estimator=DecisionTreeClassifier(),就相当于一个 随机森林的简化版本
  • 若你用其他模型(如 SVM、KNN),它依然能工作,这就是 Bagging 的灵活性。

二、Boosting(提升法)

核心思想:让后来的模型重点“学习”前面模型出错的样本。

基本思想

Boosting 采用序列训练:每一轮训练时,算法会关注前一轮中分类错误的样本,给予它们更高的权重,让后续模型更重视这些“难点样本”。最后将多个弱学习器的结果进行加权组合。

主要特点

  • 模型间有依赖关系
  • 重点在于减少偏差(bias)
  • 对噪声较敏感;
  • 一般为串行算法

类比说明

就像一个学生不断订正错误:第一次做题错了,老师就重点讲错题;第二次再练习这些题,慢慢掌握知识点。Boosting 就是这种“不断改进”的过程。

代表算法

  • AdaBoost(Adaptive Boosting):通过调整样本权重实现“自适应提升”。
  • Gradient Boosting(梯度提升):通过梯度下降优化误差。
  • XGBoost、LightGBM、CatBoost:都是现代高性能的 Boosting 框架。

一、核心思想概述

Boosting(提升法) 的主要目标是:

“把一群表现一般的模型(弱分类器)组合成一个强大的模型(强分类器)。”

Bagging(装袋法) 不同的是:

对比点BaggingBoosting
训练方式各模型独立并行训练各模型顺序依赖训练
样本权重所有样本权重相同每轮根据错误调整权重
目标降低方差降低偏差
典型算法随机森林AdaBoost、XGBoost、LightGBM

二、提升算法的关键思想:“关注错的样本”

在每一轮训练中,算法会更重视被前一轮分错的样本。

工作逻辑:

  1. 开始时,所有训练样本权重相同;

  2. 训练第 1 个分类器 M1M_1M1

  3. 检查 M1M_1M1 的分类结果;

    • 分对的样本 → 权重降低;
    • 分错的样本 → 权重升高;
  4. 使用新的权重分布训练下一个分类器 M2M_2M2,让它更关注被前一轮分错的样本;

  5. 不断迭代,得到 M1,M2,...,MKM_1, M_2, ..., M_KM1,M2,...,MK

  6. 最终,将这些模型按性能加权组合,得到强分类器。


三、类比理解

想象你在学外语:

  • 第一次考试,你发现“过去式”题总是错;
  • 第二次复习,你就重点练习这些错题
  • 第三次又发现自己“时态搭配”错了,于是再重点补;
  • 一轮轮下来,你的弱点被不断修正,整体水平自然提高。

这就是 Boosting 的思想——不断修正前一轮的错误。


四、AdaBoost(Adaptive Boosting)原理简介

AdaBoost 是 Boosting 的第一个实用版本,由 Freund 和 Schapire(1995) 提出。

算法流程(简化版)

假设我们有 NNN 个样本、要训练 KKK 个基分类器:

  1. 初始化样本权重:

    wi=1N,i=1,2,...,Nw_i = \frac{1}{N}, \quad i = 1,2,...,N wi=N1,i=1,2,...,N

  2. 循环 K 轮:

    • (1)用当前权重分布训练基分类器 MkM_kMk

    • (2)计算分类错误率:

      εk=∑iwi⋅I(Mk(xi)≠yi)\varepsilon_k = \sum_i w_i \cdot I(M_k(x_i) \neq y_i) εk=iwiI(Mk(xi)=yi)

    • (3)计算该分类器的权重:

      αk=12ln⁡(1−εkεk)\alpha_k = \frac{1}{2} \ln\left(\frac{1 - \varepsilon_k}{\varepsilon_k}\right) αk=21ln(εk1εk)

      (错误率越小,权重越大 → 表示这个模型越可靠)

    • (4)更新样本权重:

      wi←wi×e−αkyiMk(xi)w_i \leftarrow w_i \times e^{-\alpha_k y_i M_k(x_i)} wiwi×eαkyiMk(xi)

      • 分错 → 权重变大
      • 分对 → 权重变小
    • (5)归一化权重,使它们和为 1。

  3. 最终分类器:

    F(x)=sign(∑k=1KαkMk(x))F(x) = \text{sign}\left(\sum_{k=1}^K \alpha_k M_k(x)\right) F(x)=sign(k=1KαkMk(x))

    即用各个分类器的加权投票作为最终结果。


五、一个简单的 Python 示例

下面用 AdaBoostClassifier 展示它的实际效果👇

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score# 1. 加载数据
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)# 2. 创建 AdaBoost 模型(以决策树为基分类器)
ada = AdaBoostClassifier(base_estimator=DecisionTreeClassifier(max_depth=1),  # 弱分类器(桩树)n_estimators=50,                                    # 训练 50 个分类器learning_rate=1.0,                                  # 学习率(控制每轮贡献)random_state=42
)# 3. 训练并预测
ada.fit(X_train, y_train)
y_pred = ada.predict(X_test)# 4. 评估结果
print("AdaBoost 准确率:", accuracy_score(y_test, y_pred))

运行结果示例:

AdaBoost 准确率: 0.9555

六、总结对比

项目BaggingBoosting
样本选择每轮随机采样(有放回)每轮带权重采样
训练方式并行、独立串行、依赖
关注点降低方差、抗过拟合降低偏差、提高准确率
样本权重相同不同(错样本权重大)
代表算法随机森林AdaBoost、XGBoost、LightGBM


一、AdaBoostClassifier 基本说明

scikit-learn 中,AdaBoost 是通过以下类来实现的:

from sklearn.ensemble import AdaBoostClassifier

它的定义形式如下:

AdaBoostClassifier(base_estimator=None,n_estimators=50,learning_rate=1.0,algorithm='SAMME.R',random_state=None
)

二、主要参数详解

参数名含义默认值说明
base_estimator基分类器(弱学习器)None默认使用 DecisionTreeClassifier(max_depth=1),也就是“决策树桩”。可以改成 SVM、逻辑回归等。
n_estimators弱分类器的数量50表示一共要训练多少轮(即多少个弱分类器)。数量越多,模型越复杂。
learning_rate学习率1.0控制每个弱分类器的权重。较小值可以让模型更平滑、避免过拟合。
algorithm算法类型'SAMME.R''SAMME.R':使用概率输出(推荐,速度快精度高)
'SAMME':传统AdaBoost算法,适用于不输出概率的分类器。
random_state随机种子None控制实验可重复性。

三、简单理解参数作用

  • n_estimators → 训练多少个“弱模型”
  • learning_rate → 控制每个模型的影响力(相当于学习速度)
  • algorithm='SAMME.R' → 一种改进版本,速度更快、精度更高
  • base_estimator → 决定用什么算法当“基分类器”

四、一个简单的 Python 示例

我们用 Iris(鸢尾花)数据集 举例,看看 AdaBoost 的实际用法。

# 导入必要库
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.metrics import accuracy_score# 1. 加载数据
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)# 2. 创建 AdaBoost 模型
ada = AdaBoostClassifier(base_estimator=DecisionTreeClassifier(max_depth=1),  # 弱分类器:决策树桩n_estimators=50,                                     # 迭代次数learning_rate=1.0,                                   # 学习率algorithm='SAMME.R',                                 # 使用改进算法random_state=42
)# 3. 训练模型
ada.fit(X_train, y_train)# 4. 预测结果
y_pred = ada.predict(X_test)# 5. 输出准确率
print("AdaBoost 准确率:", accuracy_score(y_test, y_pred))

🧾 运行结果示例(每次略有不同)

AdaBoost 准确率: 0.9555

说明:

  • 单个弱分类器(深度为1的树)准确率不高;
  • 但经过 50 轮提升后,模型变得“越来越聪明”;
  • 最终结果通常比单一分类器明显更好。

🪄 五、总结要点

参数作用推荐值
base_estimator弱分类器类型决策树桩是最常见选择
n_estimators迭代次数50~200,一般越多越好(但过多会过拟合)
learning_rate每轮权重缩放0.5~1.0 之间调节
algorithm算法类型'SAMME.R'(默认即可)

三、Stacking(堆叠法)

核心思想:用一个“元模型”(meta-learner)来学习多个模型的输出。

基本思想

  1. 训练多个不同类型的基础模型(如决策树、SVM、神经网络等);
  2. 收集这些模型在验证集上的预测结果;
  3. 将这些预测作为输入,训练一个新的“元模型”,由它来输出最终预测。

类比说明

像一个团队决策:工程师、设计师、市场专家分别提出意见(基础模型),最后由经理(元模型)根据各方意见综合决策。

特点

  • 能综合利用不同模型的优势;
  • 容易过拟合,因此需要良好的交叉验证策略;
  • 通常性能最优,但训练复杂度较高。

常见应用

Kaggle 数据竞赛中经常使用的策略:组合多种模型(LightGBM + CNN + Logistic Regression 等)以获得最优结果。

一、Stacking 的核心思想

“让不同的模型互相取长补短,再用一个新模型来学习如何最优地融合它们。”

也就是说,Stacking 不仅仅是“平均”或“投票”,而是通过一个新的模型来“学习”各个模型的输出结果。


在这里插入图片描述
在这里插入图片描述

二、结构特点:两层(有时三层)

第一层:基分类器(Base Learners)

  • 通常选择多种不同类型的模型(例如:决策树、逻辑回归、KNN、SVM、随机森林等)。
  • 每个模型在相同的训练集上训练;
  • 每个模型独立地进行预测;
  • 这些模型的预测输出会被收集起来,作为第二层的“输入特征”。

第二层:元分类器(Meta Learner / Meta Model)

  • 第二层模型以第一层模型的输出作为输入;
  • 目标是“学习如何最优地组合这些模型的预测结果”;
  • 输出最终的分类或回归结果。

三、工作原理举例(形象版)

假设你要预测“学生是否能考上重点高中”,你找来了三种专家:

专家方法输出
专家 A看成绩(逻辑回归)0.8(考上概率)
专家 B看学习习惯(SVM)0.6
专家 C看家长学历(决策树)0.9

→ 现在你把三位专家的预测 [0.8, 0.6, 0.9] 作为一个新的特征输入,
→ 交给“总评委”(元模型,如逻辑回归)来决定最终预测。
这个总评委会自动学习哪个专家更可靠,如何加权组合结果。

这就是 Stacking 的核心逻辑:用一个模型学习如何融合多个模型的判断。


四、Stacking 的算法流程

  1. 第一层训练:

    • 用原始数据集训练多个不同的基分类器;
    • 得到它们在训练集上的预测输出。
  2. 生成第二层训练数据:

    • 以第一层模型的输出结果作为新的“输入特征”;
    • 原来的真实标签作为“输出标签”。
  3. 第二层训练:

    • 用这个新的数据集训练一个“元模型”(meta-model)。
  4. 最终预测:

    • 测试阶段,每个基模型先对测试集预测;
    • 然后将这些预测结果输入到元模型;
    • 元模型输出最终预测结果。

五、一个简单的 Python 示例

我们用 sklearn.ensemble.StackingClassifier 来演示。

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import StackingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score# 1. 加载数据
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)# 2. 定义第一层基分类器(可以是不同算法)
base_models = [('decision_tree', DecisionTreeClassifier(max_depth=3)),('svm', SVC(probability=True, kernel='linear')),
]# 3. 定义第二层元分类器(融合模型)
meta_model = LogisticRegression()# 4. 创建 Stacking 模型
stack_model = StackingClassifier(estimators=base_models,  # 第一层模型final_estimator=meta_model  # 第二层融合模型
)# 5. 训练模型
stack_model.fit(X_train, y_train)# 6. 预测与评估
y_pred = stack_model.predict(X_test)
print("Stacking 准确率:", accuracy_score(y_test, y_pred))

输出示例

Stacking 准确率: 0.9777

六、Stacking vs Bagging vs Boosting 对比总结

方法模型关系重点是否同类模型典型算法
Bagging并行、独立减少方差(抗过拟合)一般同类(如多棵树)随机森林
Boosting串行、依赖减少偏差(不断改进)一般同类AdaBoost / XGBoost
Stacking层次组合综合不同模型优势异类模型StackingClassifier

七、一句话总结

Bagging → “多次投票”
Boosting → “纠错提升”
Stacking → “融合智慧”


scikit-learnStackingClassifier 的核心构造函数。


一、基本语法

from sklearn.ensemble import StackingClassifierStackingClassifier(estimators,          # 第一层的基分类器们final_estimator=None,# 第二层元分类器cv=None,             # 交叉验证方式stack_method='auto'  # 第一层模型输出方式
)

二、参数详细讲解

参数名含义默认值说明
estimators第一层的基分类器(base learners)必填这是一个列表,格式是 [('名字1', 模型1), ('名字2', 模型2), ...]
每个模型会单独训练,并产生预测输出作为第二层的输入。
final_estimator第二层的元分类器(meta learner)None如果不指定,默认使用 LogisticRegression()
该模型负责学习如何融合第一层的输出结果。
cv交叉验证策略None控制第一层模型生成“堆叠特征”的方式。
如果为整数,如 cv=5,表示使用 5 折交叉验证。
这样可以避免“数据泄漏”,保证第二层模型更泛化。
stack_method第一层模型输出方式'auto'控制第一层模型输出给第二层模型的内容:
'auto':自动选择(分类输出概率时用 predict_proba,否则用 decision_function
'predict_proba':用概率作为输入
'decision_function':用决策函数值作为输入
'predict':用预测标签作为输入

三、参数关系图解(逻辑)

原始数据↓
[ 第一层模型 estimators ]↓       ↓       ↓[模型1预测] [模型2预测] [模型3预测]↓ (组合成新特征集)
[ 第二层模型 final_estimator ]↓最终输出结果

四、一个完整的示例

下面用鸢尾花(Iris)数据集来展示各参数如何使用👇

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import StackingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score# 1. 加载数据
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)# 2. 定义第一层模型(不同算法)
estimators = [('dt', DecisionTreeClassifier(max_depth=3)),('svm', SVC(probability=True, kernel='rbf'))
]# 3. 定义第二层融合模型(元模型)
meta_model = LogisticRegression()# 4. 创建 Stacking 模型
stack_clf = StackingClassifier(estimators=estimators,     # 第一层final_estimator=meta_model,# 第二层cv=5,                      # 使用5折交叉验证避免过拟合stack_method='auto'        # 自动决定用概率或标签
)# 5. 训练与预测
stack_clf.fit(X_train, y_train)
y_pred = stack_clf.predict(X_test)# 6. 输出结果
print("Stacking 准确率:", accuracy_score(y_test, y_pred))

运行结果示例:

Stacking 准确率: 0.9777

五、进一步说明

  • estimators
    决定第一层有哪些模型参与融合。一般建议选择差异性大的模型,如树模型 + 线性模型 + SVM。

  • final_estimator
    决定融合策略。最常用的是 LogisticRegression(),因为它可以学习各模型的权重关系。

  • cv
    推荐设置为 5 或 10,可以提高鲁棒性。
    如果设置为 cv=None,则使用训练集直接训练(速度快,但易过拟合)。

  • stack_method
    建议保持 'auto',除非你清楚需要哪种输出。
    对分类任务,通常会自动选择 predict_proba(概率输出)作为输入特征。


六、小结对比表

参数功能常见用法
estimators第一层模型[('rf', RandomForest()), ('svm', SVC())]
final_estimator第二层模型LogisticRegression()
cv交叉验证折数cv=5(推荐)
stack_method输出方式'auto'(默认)

总结对比表

方法基本思想模型关系优点缺点代表算法
Bagging随机采样训练多个模型,结果平均/投票并行、独立减少方差,抗过拟合无法降低偏差随机森林
Boosting序列训练,强化难分类样本串行、依赖减少偏差,提升准确率对噪声敏感AdaBoost、XGBoost
Stacking不同模型结果再学习层级结构综合多模型优点复杂、易过拟合各类竞赛融合模型

随机森林


一、随机森林的核心思想

随机森林(Random Forest, RF)是一种基于 Bagging(装袋法) 思想的集成学习方法,
它的基学习器(base learner) 是多棵 CART 决策树

通俗来说:

随机森林就是“很多棵随机长出来的决策树”,
最后通过“投票”来决定最终分类结果。


二、随机森林的两个“随机”

随机森林与普通 Bagging 最大的区别是,它在 两个地方都引入了随机性
从而让每棵树之间差异更大、集成效果更强。

随机环节含义作用
随机抽样样本(Bootstrap Sampling)从训练集中随机有放回地抽取样本,生成每棵树的训练集让每棵树看到的样本不同,增加模型多样性
随机抽取特征(Feature Subset Selection)在每个节点分裂时,只随机选择部分特征进行划分减少树之间的相关性,进一步提升泛化能力

这两个“随机”共同保证了森林中每棵树都不一样
从而在集成时能抵消彼此的过拟合误差


三、随机森林的训练与预测流程

(1)训练阶段:

  1. 从原始数据集中随机有放回地抽取若干样本,生成一个训练集;
  2. 从所有特征中随机选择一部分特征;
  3. 用这些样本和特征训练一棵 CART 决策树
  4. 重复上述过程 KKK 次,得到 KKK 棵不同的树;
  5. 构成整个随机森林模型。

(2)预测阶段:

  1. 每棵树分别对新的样本 x′x'x 进行预测;
  2. 分类任务:采用多数投票(majority voting);
  3. 回归任务:取所有树预测值的平均值;
  4. 最终输出作为整体预测结果。

四、与 Bagging 的关系

特点Bagging随机森林
基分类器任意模型(常用决策树)CART 决策树
样本随机性
特征随机性
优点降低方差进一步降低方差,减少树间相关性

可以理解为:

随机森林 = Bagging + 随机特征选择


五、简单 Python 示例

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score# 1. 加载数据
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)# 2. 构建随机森林模型
rf = RandomForestClassifier(n_estimators=100,     # 树的数量max_features='sqrt',  # 每次分裂时随机选择的特征数random_state=42
)# 3. 训练与预测
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)# 4. 输出结果
print("随机森林分类准确率:", accuracy_score(y_test, y_pred))

运行结果(示例):

随机森林分类准确率: 0.9777

六、总结一句话记忆法

随机森林是由多棵“随机长成”的决策树组成的森林,
每棵树都看不同的数据、不同的特征,
预测时大家投票决定最终结果。


提升树


##🌳 一、什么是“提升树”?

提升树(Boosted Tree)是一种基于提升(Boosting)思想构建的树模型集成方法
它由多棵 CART 回归树(CART Regression Tree) 叠加而成。

换句话说:

提升树不是一次性生成多棵树,而是一棵一棵地“纠错式”生成
每一棵新树都在努力修正前面所有树的错误。


二、它为什么叫“提升(Boosting)”?

“提升”指的是——
通过不断叠加弱模型(如小的决策树),
让整体模型的性能被“提升(Boosted)”起来。

与 Bagging(装袋法)不同:

  • Bagging:并行训练多棵树,平均或投票。
  • Boosting:串行训练多棵树,每棵树都在改进上一棵树的结果。

三、提升树的工作流程(核心思想)

以回归问题为例,提升树的训练过程如下👇

  1. 第一步
    用原始数据训练一棵 CART 回归树 f1(x)f_1(x)f1(x),预测目标 yyy

  2. 第二步
    计算残差(residual):

    ri=yi−f1(xi)r_i = y_i - f_1(x_i) ri=yif1(xi)

    代表模型第一次预测的“误差”。

  3. 第三步
    训练第二棵树 f2(x)f_2(x)f2(x)让它去拟合这些残差
    也就是学习第一棵树没学好的部分。

  4. 第四步
    更新整体模型:

    F2(x)=f1(x)+f2(x)F_2(x) = f_1(x) + f_2(x) F2(x)=f1(x)+f2(x)

  5. 第五步
    不断重复这个过程,第 mmm 棵树学习第 m−1m-1m1 轮的残差。

  6. 最终模型

    FM(x)=f1(x)+f2(x)+⋯+fM(x)F_M(x) = f_1(x) + f_2(x) + \cdots + f_M(x) FM(x)=f1(x)+f2(x)++fM(x)

    即多棵树的累加和(加法模型)。


四、为什么叫“梯度提升树(Gradient Boosted Tree)”?

在经典的提升树中,我们每次都在拟合残差。
而在 GBDT 中,我们把“残差”推广为损失函数的负梯度

即:

ri(m)=−∂L(yi,Fm−1(xi))∂Fm−1(xi)r_i^{(m)} = - \frac{\partial L(y_i, F_{m-1}(x_i))}{\partial F_{m-1}(x_i)} ri(m)=Fm1(xi)L(yi,Fm1(xi))

每一棵新树其实是在沿着损失函数下降最快的方向(即梯度方向)
去修正前一轮的错误。
这就是“梯度提升(Gradient Boosting)”名称的由来。


五、与随机森林的区别总结

对比项随机森林(Random Forest)提升树 / GBDT(Gradient Boosting)
思想来源Bagging(装袋)Boosting(提升)
训练方式并行训练多棵树串行训练一棵接一棵
每棵树作用独立预测,投票/平均纠错上一步误差
随机性数据和特征随机偏向梯度方向学习
模型结构平均多个模型累加多个模型
优点稳定,不易过拟合高精度,强拟合能力
缺点偏差较高训练慢,易过拟合(若树太深)

六、一个简单 Python 例子(GBDT 回归)

我们使用 scikit-learn 自带的 GradientBoostingRegressor

from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error# 1. 加载数据
X, y = load_boston(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)# 2. 创建GBDT模型
gbdt = GradientBoostingRegressor(n_estimators=100,      # 树的数量learning_rate=0.1,     # 每棵树的学习步长max_depth=3,           # 每棵树的深度random_state=42
)# 3. 训练与预测
gbdt.fit(X_train, y_train)
y_pred = gbdt.predict(X_test)# 4. 输出效果
print("GBDT 均方误差 (MSE):", mean_squared_error(y_test, y_pred))

七、一句话总结

随机森林:很多独立的树,平均投票。
梯度提升树:很多依赖的树,逐步纠错。

一个靠“随机性”减少方差,一个靠“梯度”降低偏差。


类不平衡


一、什么是“类不平衡问题”?

在分类任务中,如果某个类别的样本数量远多于其他类别,就称为“类不平衡”:

例如

类别样本数
正类(有病)100
负类(无病)10,000

模型训练时容易被“数量多的类”主导。
结果是:

  • 模型倾向于预测样本属于多数类;
  • 少数类(更重要的类,如欺诈、疾病)被忽视;
  • 虽然“总体准确率高”,但少数类的召回率(Recall)很低。

二、常见的三类解决思路

1️⃣ 抽样方法(Sampling Methods)

核心思想: 通过调整训练集样本分布,让多数类与少数类数量更加平衡。

方法类型含义常用技术优缺点
欠采样(Under-sampling)从多数类中随机删除样本,使各类样本数量接近RandomUnderSampler简单易用,但可能丢失有价值的信息
过采样(Over-sampling)复制或合成少数类样本,使样本数量增加SMOTE、ADASYN改善平衡,但可能导致过拟合
混合采样(Hybrid Sampling)同时欠采样多数类、过采样少数类SMOTE + TomekLink兼顾两者效果,较稳健

👉 示例:SMOTE(Synthetic Minority Over-sampling Technique)
通过插值的方式“合成”新的少数类样本,而不是简单复制。


2️⃣ 代价敏感方法(Cost-Sensitive Learning)

核心思想:
让模型在训练时“意识到”错误分类少数类的代价更高,从而更重视它。

方式原理举例
修改损失函数在损失函数中为少数类赋予更高权重如在逻辑回归、SVM、神经网络中设置 class_weight
修改预测阈值调整决策边界,使模型更偏向于预测少数类例如从默认 0.5 改为 0.3

👉 示例(sklearn)

from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(class_weight='balanced')

这会自动根据样本比例调整类别权重。


3️⃣ 集成学习方法(Ensemble Learning Methods)

核心思想:
利用集成技术(如 Bagging、Boosting),结合抽样或代价敏感思想,让模型更稳健地处理不平衡。

常见策略包括👇:

方法思想举例
Bagging + 抽样在每次训练子模型时对数据重新抽样(如平衡采样)Balanced Random Forest
Boosting + 权重调整在提升算法中给少数类样本更高权重AdaBoost.M1, RUSBoost, EasyEnsemble
专用算法专门设计用于不平衡问题的集成方法EasyEnsemble, BalanceCascade

👉 示例BalancedRandomForestClassifier

from imblearn.ensemble import BalancedRandomForestClassifier

它在每棵树训练时,对多数类样本随机欠采样,使森林更加平衡。


📊 三、方法对比总结表

方法类别思想核心优点缺点
抽样方法调整样本分布简单易用、模型无关可能导致信息损失或过拟合
代价敏感方法修改训练过程保留原始数据需要设定合适的权重,调参较难
集成学习方法结合多模型与抽样思想效果好、鲁棒性强计算量大,模型复杂

💡 四、小结一句话

类不平衡的本质是“模型被多数类支配”。

解决方案有三类:

  • 抽样法:改数据;
  • 代价敏感法:改损失;
  • 集成法:改模型。

三种方法可以单独用,也可以结合使用。


SMOTE(Synthetic Minority Over-sampling Technique) 是解决“类不平衡问题”中最经典、最常用的过采样算法之一。


一、SMOTE 是什么?

SMOTE 的中文名是 合成少数类过采样技术
它通过在特征空间中“合成”新的少数类样本,而不是简单地复制已有样本,从而让数据更加平衡。


二、它是怎么“合成”新样本的?

传统的“过采样”往往只是重复复制少数类样本,容易导致过拟合。
SMOTE 的做法更聪明:

主要步骤:

  1. 对于每个少数类样本 xix_ixi,找到它在少数类样本中的 k 个最近邻样本

  2. 从这些邻居中随机选择一个样本 xjx_jxj

  3. xix_ixixjx_jxj 之间,按比例随机插值生成一个新的样本点

    xnew=xi+λ×(xj−xi)x_{new} = x_i + \lambda \times (x_j - x_i) xnew=xi+λ×(xjxi)

    其中 λ∈[0,1]\lambda \in [0,1]λ[0,1]

这样生成的新样本“位于原始样本之间”,
即:

  • 不会重复已有样本;
  • 也能保留数据的几何结构;
  • 避免模型只记住少数类的具体样本。

三、SMOTE 的优点与局限

优点缺点
不会简单复制样本,减少过拟合风险可能在噪声点周围生成错误样本
保留了少数类的分布结构对类别分布重叠的边界不敏感
实现简单,效果显著对高维数据或异常点敏感

四、Python 实例演示(使用 imblearn 库)

下面用一个简单的二分类例子演示 SMOTE 的使用。

# 导入库
from sklearn.datasets import make_classification
from imblearn.over_sampling import SMOTE
from collections import Counter
import matplotlib.pyplot as plt# 1. 构造一个不平衡数据集
X, y = make_classification(n_samples=200,       # 样本总数n_features=2,        # 特征数量(方便可视化)n_classes=2,         # 二分类weights=[0.9, 0.1],  # 类别比例(不平衡)random_state=42
)print("SMOTE前:", Counter(y))# 2. 应用SMOTE过采样
smote = SMOTE(random_state=42)
X_res, y_res = smote.fit_resample(X, y)print("SMOTE后:", Counter(y_res))# 3. 可视化对比
plt.figure(figsize=(10,4))plt.subplot(1,2,1)
plt.title("SMOTE前(不平衡)")
plt.scatter(X[y==0][:,0], X[y==0][:,1], label='多数类', alpha=0.6)
plt.scatter(X[y==1][:,0], X[y==1][:,1], label='少数类', alpha=0.6, color='red')
plt.legend()plt.subplot(1,2,2)
plt.title("SMOTE后(平衡)")
plt.scatter(X_res[y_res==0][:,0], X_res[y_res==0][:,1], label='多数类', alpha=0.6)
plt.scatter(X_res[y_res==1][:,0], X_res[y_res==1][:,1], label='少数类(含合成样本)', alpha=0.6, color='red')
plt.legend()plt.show()

运行结果解释

输出:

SMOTE前: Counter({0: 180, 1: 20})
SMOTE后: Counter({0: 180, 1: 180})

图像上可以看到:

  • 左边:少数类(红点)明显比多数类(蓝点)少;
  • 右边:SMOTE 生成了大量新红点,它们分布在原少数类样本之间,数据变得更平衡。

五、总结一句话

SMOTE 的核心思想是:

“在少数类样本之间插值,合成新的样本点,而不是复制已有样本。”

它让模型更公平地学习不同类别的特征,提高少数类的识别能力。


“SMOTE + 随机森林分类” 实战案例


一、实验目标

验证:

使用 SMOTE 过采样后,模型对“少数类”的识别能力显著提升。


二、完整 Python 示例代码

# 导入所需库
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
from imblearn.over_sampling import SMOTE
from collections import Counter# 1. 构造一个不平衡二分类数据集
X, y = make_classification(n_samples=1000,       # 总样本数n_features=6,         # 特征数n_classes=2,          # 二分类weights=[0.9, 0.1],   # 类别比例(严重不平衡)random_state=42
)print("原始类别分布:", Counter(y))# 2. 划分训练集与测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)# 3. ------------------ 未使用SMOTE ------------------
rf1 = RandomForestClassifier(random_state=42)
rf1.fit(X_train, y_train)
y_pred1 = rf1.predict(X_test)print("\n【未使用SMOTE】模型表现:")
print(confusion_matrix(y_test, y_pred1))
print(classification_report(y_test, y_pred1, digits=3))# 4. ------------------ 使用SMOTE过采样 ------------------
smote = SMOTE(random_state=42)
X_train_res, y_train_res = smote.fit_resample(X_train, y_train)print("\nSMOTE后类别分布:", Counter(y_train_res))rf2 = RandomForestClassifier(random_state=42)
rf2.fit(X_train_res, y_train_res)
y_pred2 = rf2.predict(X_test)print("\n【使用SMOTE】模型表现:")
print(confusion_matrix(y_test, y_pred2))
print(classification_report(y_test, y_pred2, digits=3))

三、结果示例(输出解释)

假设输出如下:

原始类别分布: Counter({0: 900, 1: 100})【未使用SMOTE】模型表现:
[[268   3][ 24   5]]precision    recall  f1-score   support0      0.918     0.989     0.952       2711      0.625     0.172     0.270        29【使用SMOTE】模型表现:
[[264   7][ 10  19]]precision    recall  f1-score   support0      0.964     0.974     0.969       2711      0.731     0.655     0.691        29

四、结果分析

指标未使用 SMOTE使用 SMOTE
少数类召回率(Recall)0.1720.655↑
少数类精确率(Precision)0.6250.731
少数类 F1-score0.2700.691↑

可以看到:

  • 使用 SMOTE 后,模型明显更能识别少数类样本
  • 尽管总体准确率变化不大,但模型的公平性和敏感性提高了
  • 这在医学诊断、欺诈检测等场景非常重要(宁愿多报错一些,也不漏报关键少数类)。

五、小结一句话

SMOTE + 随机森林 是应对类不平衡问题的经典组合:
SMOTE 负责“生成平衡数据”,
随机森林负责“鲁棒建模”,
二者结合既提升少数类召回率,又保持整体性能稳定。


ADASYN(Adaptive Synthetic Sampling) 是一种比 SMOTE 更“聪明”的少数类过采样算法。


一、ADASYN 的核心思想

SMOTE 是在少数类样本之间均匀地合成新样本。
而 ADASYN 是在少数类样本之间**“自适应地”**合成样本:

  • 重点加强困难样本的生成
    它会评估哪些少数类样本更“难学”(即离多数类更近、容易被误判),
    然后在这些区域生成更多合成样本。

  • 简单样本少生成,难样本多生成
    因此生成的新样本分布会自动偏向“模型不容易学对的地方”,
    从而提升模型整体的分类能力。


二、算法步骤概述

  1. 计算每个少数类样本的难度权重

    • 使用 KNN(常取 k=5)找出该少数类样本邻域内多数类样本的比例。
    • 多数类比例越高 → 样本越难学习 → 权重越大。
  2. 确定生成样本数量

    • 生成的样本数与难度成正比。
  3. 合成新样本

    • 对于被选中的少数类样本,用与 SMOTE 相似的方式(线性插值)生成新样本:

      xnew=xi+δ×(xzi−xi)x_{new} = x_i + \delta \times (x_{zi} - x_i) xnew=xi+δ×(xzixi)

      其中 δ\deltaδ 为 [0,1] 之间的随机数。


三、Python 实例:SMOTE vs ADASYN

from sklearn.datasets import make_classification
from imblearn.over_sampling import SMOTE, ADASYN
from collections import Counter
import matplotlib.pyplot as plt# 1. 生成一个不平衡数据集
X, y = make_classification(n_samples=500, n_features=2, n_redundant=0,n_clusters_per_class=1, weights=[0.9, 0.1],random_state=42
)
print("原始分布:", Counter(y))# 2. 使用 SMOTE
smote = SMOTE(random_state=42)
X_sm, y_sm = smote.fit_resample(X, y)
print("SMOTE后:", Counter(y_sm))# 3. 使用 ADASYN
adasyn = ADASYN(random_state=42)
X_ad, y_ad = adasyn.fit_resample(X, y)
print("ADASYN后:", Counter(y_ad))# 4. 可视化比较
plt.figure(figsize=(10,4))
plt.subplot(1,2,1)
plt.scatter(X_sm[:,0], X_sm[:,1], c=y_sm, cmap='coolwarm', s=15)
plt.title("SMOTE 生成分布")plt.subplot(1,2,2)
plt.scatter(X_ad[:,0], X_ad[:,1], c=y_ad, cmap='coolwarm', s=15)
plt.title("ADASYN 生成分布")plt.show()

四、结果与区别

特点SMOTEADASYN
采样策略均匀生成根据样本难度自适应生成
新样本位置分布较规则更集中于边界或难分类区域
适用场景普通不平衡数据类间边界模糊、难分数据

五、小结一句话

ADASYN = “更聪明的 SMOTE”
它让模型把注意力更多地放在“最难学”的少数类样本上,
从而提升模型的泛化能力和鲁棒性。

“ADASYN + 随机森林分类” 实战案例。


一、实验目标

验证:

使用 ADASYN 过采样后,模型对“少数类”的识别能力显著提升。


二、完整 Python 示例代码

# 导入必要的库
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
from imblearn.over_sampling import ADASYN
from collections import Counter# 1️⃣ 构造一个不平衡二分类数据集
X, y = make_classification(n_samples=1000,        # 样本总数n_features=6,          # 特征数量n_classes=2,           # 二分类weights=[0.9, 0.1],    # 类别比例(严重不平衡)random_state=42
)
print("原始类别分布:", Counter(y))# 2️⃣ 划分训练集与测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y
)# 3️⃣ 未使用ADASYN的随机森林模型
rf_no_adasyn = RandomForestClassifier(random_state=42)
rf_no_adasyn.fit(X_train, y_train)
y_pred_no = rf_no_adasyn.predict(X_test)print("\n【未使用ADASYN】模型表现:")
print(confusion_matrix(y_test, y_pred_no))
print(classification_report(y_test, y_pred_no, digits=3))# 4️⃣ 使用ADASYN过采样
adasyn = ADASYN(random_state=42)
X_train_res, y_train_res = adasyn.fit_resample(X_train, y_train)print("\nADASYN后类别分布:", Counter(y_train_res))# 5️⃣ 使用ADASYN后的随机森林模型
rf_adasyn = RandomForestClassifier(random_state=42)
rf_adasyn.fit(X_train_res, y_train_res)
y_pred_adasyn = rf_adasyn.predict(X_test)print("\n【使用ADASYN】模型表现:")
print(confusion_matrix(y_test, y_pred_adasyn))
print(classification_report(y_test, y_pred_adasyn, digits=3))

三、结果示例(运行后可能略有差异)

原始类别分布: Counter({0: 900, 1: 100})【未使用ADASYN】模型表现:
[[269   2][ 25   4]]precision    recall  f1-score   support0      0.915     0.993     0.953       2711      0.667     0.138     0.228        29ADASYN后类别分布: Counter({0: 630, 1: 630})【使用ADASYN】模型表现:
[[265   6][  9  20]]precision    recall  f1-score   support0      0.967     0.978     0.972       2711      0.769     0.690     0.727        29

四、结果分析

指标未使用 ADASYN使用 ADASYN
少数类召回率(Recall)0.1380.690↑
少数类精确率(Precision)0.6670.769
少数类 F1-score0.2280.727↑

使用 ADASYN 后,少数类样本的识别能力显著提升,模型对两类数据的表现更加均衡。
特别是 Recall(召回率)提升最明显,这对于医疗诊断、欺诈检测等任务尤其重要。


五、对比 SMOTE 的特点

方法样本生成策略生成位置分布适用场景
SMOTE均匀生成较平滑、分布均衡一般不平衡数据
ADASYN根据样本难度自适应生成更集中于难分类区域类间边界模糊、少数类稀疏时

六、小结一句话

ADASYN + 随机森林 是解决复杂类不平衡问题的强力组合:
ADASYN 让数据更“聪明”地补平衡,
随机森林让模型更“稳健”地分类。


EasyEnsemble(易集成)”算法。它特别适合处理“多数类样本远多于少数类样本”的严重不平衡场景(比如欺诈检测、疾病筛查等)。


一、EasyEnsemble 的核心思想

EasyEnsemble 是一种 基于集成学习的欠采样(Under-sampling)方法

它的基本思路是:

不一次性丢掉多数类样本,而是多次随机抽取多数类子集,
与全部少数类样本组合成多个“平衡子数据集”,
然后分别训练多个分类器,
最后再对这些分类器的预测结果进行集成(投票或加权平均)。


二、算法原理详解

假设原始数据集中:

  • 多数类样本:900 个
  • 少数类样本:100 个

EasyEnsemble 步骤:

1️⃣ 随机欠采样

  • 从多数类样本中随机抽取与少数类样本数量相同的样本(100 个),
    与少数类样本一起构成一个平衡数据集(共 200 个样本)。
  • 重复这个过程多次(比如抽取 10 组),得到多个不同的平衡训练集。

2️⃣ 训练多个分类器

  • 对每个平衡数据集都单独训练一个基分类器(通常使用 AdaBoost 或随机森林)。

3️⃣ 集成预测

  • 测试时,将多个模型的预测结果进行加权平均或投票
    得到最终的分类结果。

三、EasyEnsemble 的优势

优点说明
✅ 充分利用多数类样本虽然每次只用部分样本,但通过多次抽样,所有样本都有机会参与训练。
✅ 不引入合成样本与 SMOTE、ADASYN 不同,它不“虚构”数据,保持数据真实。
✅ 适合极度不平衡数据尤其适用于多数类样本数量极多、少数类极少的情况。
✅ 可与 Boosting 结合形成 EasyEnsemble AdaBoost(性能更强)。

四、简单 Python 案例(使用 imblearn.ensemble.EasyEnsembleClassifier

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix
from imblearn.ensemble import EasyEnsembleClassifier
from collections import Counter# 1️⃣ 生成一个严重不平衡的数据集
X, y = make_classification(n_samples=2000, n_features=6,n_classes=2, weights=[0.95, 0.05],random_state=42
)
print("原始类别分布:", Counter(y))# 2️⃣ 划分训练集与测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y
)# 3️⃣ 创建 EasyEnsemble 模型
eec = EasyEnsembleClassifier(n_estimators=10,    # 集成的子模型数量random_state=42
)
eec.fit(X_train, y_train)
y_pred = eec.predict(X_test)# 4️⃣ 模型表现
print("\n混淆矩阵:")
print(confusion_matrix(y_test, y_pred))
print("\n分类报告:")
print(classification_report(y_test, y_pred, digits=3))

五、运行结果示例

原始类别分布: Counter({0: 1900, 1: 100})混淆矩阵:
[[541   30][ 10   19]]分类报告:precision    recall  f1-score   support0      0.982     0.947     0.964       5711      0.388     0.655     0.488        29

可以看到:

  • 尽管少数类比例非常低(5%),
  • EasyEnsemble 依然能保持不错的识别能力(Recall 达到 0.65)。
    这正体现了它在极端不平衡数据下的鲁棒性。

六、小结一句话

EasyEnsemble = 多次欠采样 + 集成学习。
它不创造数据,而是通过“多次利用数据”提升少数类识别能力,
是一种高效、稳健、实用的应对类不平衡的集成算法。


案例

EasyEnsemble、AdaBoost、SMOTE+随机森林(SMOTE+RF) 三种方法


一、对比目标

我们将比较三种模型的表现(主要看 少数类 Recall、F1-score):

模型名称方法类型主要思想
AdaBoost普通集成模型不考虑类别不平衡
SMOTE + 随机森林过采样 + 集成通过SMOTE合成样本平衡数据
EasyEnsembleClassifier欠采样 + 集成多次随机欠采样 + AdaBoost 集成

二、完整 Python 实战代码

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import AdaBoostClassifier, RandomForestClassifier
from sklearn.metrics import classification_report
from imblearn.ensemble import EasyEnsembleClassifier
from imblearn.over_sampling import SMOTE
from collections import Counter# 1️⃣ 生成一个严重不平衡的数据集
X, y = make_classification(n_samples=3000, n_features=10,n_informative=6, n_redundant=2,n_classes=2, weights=[0.95, 0.05],  # 极度不平衡random_state=42
)
print("原始类别分布:", Counter(y))# 2️⃣ 划分训练集与测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y, random_state=42
)# ------------------ 模型①:普通 AdaBoost ------------------
ada = AdaBoostClassifier(n_estimators=100, random_state=42)
ada.fit(X_train, y_train)
y_pred_ada = ada.predict(X_test)
print("\n【AdaBoost】分类报告:")
print(classification_report(y_test, y_pred_ada, digits=3))# ------------------ 模型②:SMOTE + 随机森林 ------------------
smote = SMOTE(random_state=42)
X_train_sm, y_train_sm = smote.fit_resample(X_train, y_train)
print("SMOTE后类别分布:", Counter(y_train_sm))rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train_sm, y_train_sm)
y_pred_rf = rf.predict(X_test)
print("\n【SMOTE + 随机森林】分类报告:")
print(classification_report(y_test, y_pred_rf, digits=3))# ------------------ 模型③:EasyEnsemble ------------------
eec = EasyEnsembleClassifier(n_estimators=10,  # 集成的子模型数量random_state=42
)
eec.fit(X_train, y_train)
y_pred_eec = eec.predict(X_test)
print("\n【EasyEnsemble】分类报告:")
print(classification_report(y_test, y_pred_eec, digits=3))

三、示例结果(可能略有浮动)

假设输出如下(随机数据示例):

【AdaBoost】

precision    recall  f1-score   support
0      0.97     1.00     0.99       855
1      0.75     0.18     0.29        45

【SMOTE + 随机森林】

precision    recall  f1-score   support
0      0.99     0.97     0.98       855
1      0.65     0.73     0.69        45

【EasyEnsemble】

precision    recall  f1-score   support
0      0.97     0.97     0.97       855
1      0.68     0.78     0.73        45

四、结果对比分析

模型少数类 Recall少数类 Precision少数类 F1说明
AdaBoost0.180.750.29传统方法,几乎忽略少数类
SMOTE + 随机森林0.730.650.69通过合成样本改善了识别能力
EasyEnsemble0.780.680.73表现最优,稳定识别少数类

五、总结对比

特点AdaBoostSMOTE+RFEasyEnsemble
核心思想权重提升,未考虑不平衡过采样平衡数据多次欠采样 + 集成
是否合成数据
少数类识别能力较好最好
对极端不平衡数据适应性
训练时间中等稍慢(多模型)

结论:

  • AdaBoost:适合数据较平衡场景;
  • SMOTE + RF:适合中度不平衡;
  • EasyEnsemble:在极度不平衡情况下表现最稳健,少数类 Recall 最高。

六、一句话总结

EasyEnsemble 是处理极度类不平衡问题的强力武器
它通过多次欠采样 + 集成学习,
避免了过采样的噪声问题,同时最大限度利用多数类样本。


http://www.dtcms.com/a/504510.html

相关文章:

  • 网站建设广东猎头公司收费
  • 【Android】BottomNavigationView实现底部导航栏
  • 小程序开发需要多少钱宁波seo外包服务商
  • XSS攻击防范:从入门到精通
  • 做云购网站网站框架怎么做
  • 建中英文网站网络优化公司有哪些
  • 详细讲解java中的方法(适合新手小白)
  • vip解析网站怎么做网络搜索词排名
  • 最新网站域名如何寻找网站建设需求客户
  • 河北网站建设推广如何制作活动宣传网页
  • Linux memfree 的计算逻辑
  • 宁波网站建设软件开发医药公司网站建设备案
  • 一 网站建设的目的和目标辽宁网站建站优化公司
  • 网站开发本地环境seo排名怎么做
  • 网站首页置顶是怎么做单页展示网站
  • 微信网页上的网站怎么做的网站响应时间方案
  • ScheduledExecutorService
  • 网站首页新世纪建设集团有限公司长沙网站seo收费
  • 网站优化的论文pc网站建设企业
  • 各个视频网站怎么做原创作者南宁市建筑规划设计集团有限公司
  • 探索Word2Vec:从文本向量化到中文语料处理
  • 性能测试 | 认识性能测试的概念以及应用
  • 小企业网站建设论文东莞网站建设设计
  • 第23讲:文件操作
  • 网站如何不需要备案免费发广告的软件有哪些
  • 网站制作 需要什么网络技术唯品会网站建设特色
  • 如何提高网站点击率dns网站建设
  • 响应式布局的原理网站meta 优化建议
  • 网站建设设计收费网络销售面试问题有哪些
  • mysql8支持远程访问 -mysql5.7支持远程访问