问题现象描述
当开发者使用RandomUnderSampler处理类别不平衡数据时,经常会遇到如下报错:
ValueError: Expected n_neighbors <= n_samples,
but n_samples = 5, n_neighbors = 6
这个错误通常发生在少数类样本数量极少的情况下,特别是在配置RandomUnderSampler时启用了k_neighbors参数或使用某些特定采样策略时。
错误原理分析
该错误的根本原因在于样本数量与邻域参数的冲突:
- 当少数类样本数量小于
n_neighbors参数时,K近邻算法无法计算有效邻域 RandomUnderSampler内部某些版本会默认调用KNN进行样本验证- 数据集经过前期预处理后可能导致某些类别样本数骤减
5种解决方案
1. 调整采样策略参数
显式设置sampling_strategy参数,避免自动模式下的邻域计算:
from imblearn.under_sampling import RandomUnderSampler
sampler = RandomUnderSampler(
sampling_strategy={0: 100, 1: 50}, # 明确指定采样数量
random_state=42
)
2. 禁用KNN验证
在较新版本中可以通过设置验证参数:
sampler = RandomUnderSampler(
sampling_strategy='auto',
n_neighbors=None, # 显式禁用KNN
verification=False # 关闭验证步骤
)
3. 预处理样本过滤
在采样前检查并过滤极小样本类:
from collections import Counter
count = Counter(y)
min_samples = min(count.values())
if min_samples < 5: # 设置合理阈值
# 执行特殊处理逻辑
4. 使用其他采样方法
考虑组合采样策略:
from imblearn.combine import SMOTEENN
sampler = SMOTEENN(sampling_strategy='auto')
5. 版本降级/升级
不同版本处理逻辑差异:
- 0.6.x版本:默认启用KNN验证
- 0.7+版本:优化了验证逻辑
最佳实践建议
| 场景 | 推荐方案 |
|---|---|
| 极少数类样本(<5个) | 人工增补数据或删除该类别 |
| 中等不平衡数据 | RandomUnderSampler+SMOTE组合 |
| 高维数据 | TSNE降维后采样 |
完整示例代码
from imblearn.under_sampling import RandomUnderSampler
from sklearn.datasets import make_classification
X, y = make_classification(
n_samples=1000,
weights=[0.95, 0.05],
random_state=42
)
# 安全采样方案
safe_sampler = RandomUnderSampler(
sampling_strategy='not minority',
replacement=False,
random_state=42,
verification=False
)
X_res, y_res = safe_sampler.fit_resample(X, y)