目录

SMOTE过采样实现过程详解

SMOTE过采样实现过程详解

引言

SMOTE(Synthetic Minority Over-sampling Technique,合成少数类过采样技术)是一种常用的处理类别不平衡问题的方法。下面我将详细解释oversampler=SMOTE(random_state=0)os_x_train,os_y_train=oversampler.fit_resample(x_train_w,y_train_w)这两行代码的实现过程。

1. SMOTE的基本原理

SMOTE通过在少数类样本之间进行插值来生成新的合成样本,而不是简单地复制现有样本。其主要思想是:

  1. 对于每一个少数类样本,找到它的k个最近邻(通常是欧氏距离)
  2. 在这些近邻中随机选择一个样本
  3. 在这两个样本之间的连线上随机选择一个点作为新的合成样本

2. 代码实现过程详解

2.1 SMOTE初始化


oversampler = SMOTE(random_state=0)
  • random_state=0:设置随机种子,确保每次运行结果可复现

  • 默认参数:

    • k_neighbors=5:查找最近邻的数量
    • sampling_strategy='auto':默认将少数类样本数量增加到与多数类相同

2.2 数据重采样过程


os_x_train, os_y_train = oversampler.fit_resample(x_train_w, y_train_w)

fit_resample()方法的执行步骤如下:

步骤1:分析类别分布
  1. 统计y_train_w中各个类别的样本数量
  2. 确定少数类(样本数量最少的类别)和多数类
  3. 计算需要生成的合成样本数量(默认使少数类样本数量等于多数类)
步骤2:生成合成样本

对于每一个少数类样本:

  1. ​查找k近邻​​:

    • 计算该样本与所有其他少数类样本的距离(默认使用欧氏距离)
    • 找出距离最近的k个样本(默认k=5)
  2. ​随机选择邻居​​:

    • 从k个近邻中随机选择一个样本
    • 使用random_state确保可复现性
  3. ​生成合成样本​​:

    • 在两个样本之间随机选择一个点
    • 新样本的计算公式:新样本 = 原始样本 + random(0,1) * (邻居样本 - 原始样本)
    • random(0,1)表示0到1之间的随机数
步骤3:构建新数据集
  1. 将原始少数类样本与新生成的合成样本合并
  2. 保持多数类样本不变
  3. 返回新的特征矩阵os_x_train和标签向量os_y_train

2.3 示例说明

假设原始数据集:

  • 多数类(类别0):1000个样本
  • 少数类(类别1):100个样本

执行SMOTE后:

  • 类别0保持不变(1000个样本)
  • 类别1增加到1000个样本(原始100个 + 新生成900个合成样本)

3. SMOTE的参数详解

参数说明默认值
k_neighbors用于生成新样本的最近邻数量5
sampling_strategy重采样策略‘auto’
random_state随机种子None
n_jobs并行计算使用的CPU核心数None

sampling_strategy可选值:

  • ‘auto’:将少数类样本数量增加到与多数类相同
  • ‘minority’:仅对少数类进行过采样
  • float:指定少数类样本数量与多数类的比例(如0.5表示达到多数类的一半)
  • dict:指定每个类别需要达到的样本数量

4. SMOTE的优缺点

优点:

  1. 避免简单复制导致的过拟合
  2. 在特征空间内合理扩展少数类样本
  3. 适用于高维数据

缺点:

  1. 可能生成噪声样本(当少数类样本分布不连续时)
  2. 对高维稀疏数据效果可能不佳
  3. 可能忽略类别内部的子类别结构

5. 使用建议

  1. 先进行数据探索,了解少数类样本的分布
  2. 尝试不同的k_neighbors值(3-10)
  3. 结合欠采样方法使用(如SMOTE + Tomek Links)
  4. 对于高维数据,考虑先进行降维

6. 可视化示例


from imblearn.over_sampling import SMOTE
import matplotlib.pyplot as plt
import numpy as np

# 创建不平衡数据集
X = np.random.randn(100, 2)
y = np.array([0]*90 + [1]*10)

# 应用SMOTE
smote = SMOTE(random_state=42)
X_res, y_res = smote.fit_resample(X, y)

# 可视化
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.scatter(X[y==0, 0], X[y==0, 1], label="Majority")
plt.scatter(X[y==1, 0], X[y==1, 1], label="Minority")
plt.title("Original Data")

plt.subplot(1, 2, 2)
plt.scatter(X_res[y_res==0, 0], X_res[y_res==0, 1], label="Majority")
plt.scatter(X_res[y_res==1, 0], X_res[y_res==1, 1], label="Minority (SMOTE)")
plt.title("After SMOTE")
plt.legend()
plt.show()

这个示例展示了SMOTE如何通过在少数类样本之间生成新样本来平衡数据集。