数据, 术→技巧

数据处理之重采样(过采样与欠采样)

钱魏Way · · 240 次浏览

重采样(Resampling) 是处理数据不平衡问题的核心技术之一,通过调整训练数据中不同类别的样本比例,使模型更关注少数类。

重采样的两类核心方法

过采样(Oversampling)

目标:增加少数类样本数量,平衡类别分布。

适用场景:当少数类样本数量较少时(如医疗罕见病诊断、金融欺诈检测)。

随机过采样(Random Oversampling)

  • 原理:通过随机复制少数类样本,直接增加其数量。
  • 步骤
    • 统计少数类样本数量$N_{\text{minority}}$。
    • 从少数类中随机选择样本(允许重复选择),直到其数量与多数类平衡。
  • 优点:简单快速,适用于小规模数据。
  • 缺点
    • 容易导致模型过拟合(重复样本降低了泛化能力)。
    • 对噪声样本敏感(可能放大噪声的影响)。

代码示例:

from sklearn.utils import resample

# 假设 minority_df 是少数类样本,majority_df 是多数类样本
minority_upsampled = resample(minority_df, 
                             replace=True,     # 允许重复采样
                             n_samples=len(majority_df), 
                             random_state=42)
balanced_df = pd.concat([majority_df, minority_upsampled])

SMOTE(Synthetic Minority Oversampling Technique)

  • 原理:通过线性插值生成新的合成样本,而非简单复制。
    • 对每个少数类样本$x_i$,随机选择其最近的 k个同类邻居。
    • 在$x_i$和邻居之间随机选择一个点,生成新样本。
  • 步骤
    • 计算少数类样本的k 近邻(通常 k=5)。
    • 在样本与邻居的连线上随机插值生成新样本。
  • 优点:缓解过拟合问题,生成多样化的新样本。
  • 缺点
    • 可能生成不合理的样本(尤其在类别边界模糊时)。
    • 对高维数据效果可能下降。

代码示例:

from imblearn.over_sampling import SMOTE

smote = SMOTE(sampling_strategy='auto', k_neighbors=5, random_state=42)
X_resampled, y_resampled = smote.fit_resample(X, y)

ADASYN(Adaptive Synthetic Sampling)

  • 原理:动态调整生成样本的数量,优先在分类边界附近生成样本。
    • 根据少数类样本的密度分布,对难以分类的样本生成更多合成数据。
  • 步骤
    • 计算每个少数类样本需要生成的新样本数量(密度低的区域生成更多)。
    • 使用类似SMOTE的插值方法生成样本。
  • 优点:更关注分类边界,提升模型对复杂分布的捕捉能力。
  • 缺点:可能放大噪声的影响。

代码示例:

from imblearn.over_sampling import ADASYN

adasyn = ADASYN(sampling_strategy='auto', n_neighbors=5, random_state=42)
X_resampled, y_resampled = adasyn.fit_resample(X, y)

其他高级过采样方法

  • Borderline-SMOTE:仅对处于类别边界的少数类样本生成新数据。
  • SVMSMOTE:使用SVM支持向量机识别边界样本后再生成数据。

欠采样(Undersampling)

目标:减少多数类样本数量,平衡类别分布。

适用场景:当多数类样本数量极大时(如用户流失预测、网络入侵检测)。

随机欠采样(Random Undersampling)

  • 原理:随机删除多数类样本,直到类别平衡。
  • 步骤
    • 统计多数类样本数量$N_{\text{majority}}$。
    • 随机选择$N_{\text{minority}}$ 个多数类样本保留,其余删除。
  • 优点:简单高效,降低计算成本。
  • 缺点
    • 可能丢失重要信息(尤其是多数类内部的关键模式)。
    • 对噪声敏感(可能保留噪声样本)。

代码示例:

from sklearn.utils import resample

# 假设 majority_df 是多数类样本
majority_downsampled = resample(majority_df,
                               replace=False,    # 不允许重复采样
                               n_samples=len(minority_df),
                               random_state=42)
balanced_df = pd.concat([minority_df, majority_downsampled])

NearMiss

  • 原理:基于距离选择与少数类样本最相关的多数类样本。
    • NearMiss-1:保留与每个少数类样本最近的多数类样本。
    • NearMiss-2:保留与每个少数类样本最远的多数类样本。
    • NearMiss-3:为每个少数类样本保留一定数量的最近多数类样本。
  • 优点:保留与少数类相关的关键多数类样本。
  • 缺点:计算复杂度较高(需计算样本间距离)。

代码示例:

from imblearn.under_sampling import NearMiss

near_miss = NearMiss(version=3, n_neighbors=3)
X_resampled, y_resampled = near_miss.fit_resample(X, y)

Tomek Links

  • 原理:删除多数类中与少数类样本形成Tomek Link的样本。
    • 若两个不同类别的样本互为最近邻,则称为Tomek Link,通常位于类别边界。
  • 步骤
    • 找到所有Tomek Link对。
    • 删除其中的多数类样本。
  • 优点:清理类别边界,提升模型对边界的区分能力。
  • 缺点:单独使用可能欠采样不足,需结合其他方法。

代码示例:

from imblearn.under_sampling import TomekLinks

tl = TomekLinks()
X_resampled, y_resampled = tl.fit_resample(X, y)

其他高级欠采样方法

  • Cluster Centroids:对多数类样本聚类后,用聚类中心代替原始样本。
  • ENN(Edited Nearest Neighbours):删除被多数近邻包围的多数类样本。

组合方法(Hybrid Approaches)

结合过采样和欠采样,兼顾信息保留与计算效率。

  • SMOTE + Tomek Links
    • 使用SMOTE生成少数类样本。
    • 用Tomek Links清理边界噪声。
  • SMOTE + ENN
    • 生成合成样本。
    • 删除噪声样本。

代码示例:

from imblearn.combine import SMOTEENN

smote_enn = SMOTEENN(smote=SMOTE(sampling_strategy='auto'), enn=EditedNearestNeighbours())
X_resampled, y_resampled = smote_enn.fit_resample(X, y)

重采样的注意事项

  • 避免数据泄露:先拆分训练集和测试集,再对训练集重采样(测试集必须保持原始分布)。
  • 评估指标选择:使用F1-Score、AUC-ROC等对不平衡数据更敏感的指标。
  • 过采样与欠采样的权衡:过采样适合小规模数据,但可能过拟合;欠采样适合大规模数据,但可能丢失信息。
  • 领域知识结合:例如在金融欺诈检测中,需谨慎生成合成样本,避免破坏交易模式。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注