使用imbalanced-learn的sample_cleaning方法时遇到"样本清洗过度导致信息丢失"问题如何解决?

一、问题现象与背景

在使用imbalanced-learn库的sample_cleaning方法(如TomekLinksEditedNearestNeighbours)时,用户经常遇到一个典型问题:过度清洗导致少数类样本严重损失。例如当处理医学诊断数据集时,原本1000:100的类别比例,在清洗后可能变为800:30,反而加剧了类别不平衡。

二、问题产生机制

该问题主要由以下因素共同作用:

  • KNN参数设置不当:邻居数量(k值)过小会过度敏感
  • 数据分布特性:高维稀疏数据更易受影响
  • 边界样本判定:重叠区域的样本易被误删
  • 算法链式效应:多个清洗方法叠加使用

三、诊断方法

通过以下Python代码可快速诊断问题:

from imblearn.under_sampling import TomekLinks
from collections import Counter

# 原始数据分布
print("Original distribution:", Counter(y))

# 应用清洗方法
tl = TomekLinks()
X_res, y_res = tl.fit_resample(X, y)

# 清洗后分布
print("Cleaned distribution:", Counter(y_res))

# 计算损失比例
minority_loss = 1 - (Counter(y_res)[1] / Counter(y)[1])
print(f"Minority class loss: {minority_loss:.1%}")

四、解决方案

1. 参数优化策略

参数 推荐值 作用
n_neighbors 5-15 控制邻居范围
sampling_strategy 'auto'或指定比例 限制最大删除量

2. 方法组合技巧

建议采用管道式处理

  1. 先使用RandomUnderSampler初步平衡
  2. 再用SMOTE生成合成样本
  3. 最后用TomekLinks精细清理

3. 替代方案

当持续出现信息丢失时,可考虑:

  • NearMiss版本3:基于最远邻的欠采样
  • InstanceHardnessThreshold:基于模型预测
  • OneSidedSelection:组合式方法

五、最佳实践案例

信用卡欺诈检测中的优化配置:

from imblearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import TomekLinks

pipeline = Pipeline([
    ('oversample', SMOTE(sampling_strategy=0.3)),
    ('clean', TomekLinks(n_neighbors=10))
])

X_res, y_res = pipeline.fit_resample(X, y)

此方案可将少数类损失控制在<15%以内,同时显著提升模型AUC分数。