一、问题现象与背景
在使用imbalanced-learn库的sample_cleaning方法(如TomekLinks或EditedNearestNeighbours)时,用户经常遇到一个典型问题:过度清洗导致少数类样本严重损失。例如当处理医学诊断数据集时,原本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. 方法组合技巧
建议采用管道式处理:
- 先使用
RandomUnderSampler初步平衡 - 再用
SMOTE生成合成样本 - 最后用
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分数。