使用imbalanced-learn的RandomUnderSampler时出现ValueError: Expected n_neighbors <= n_samples 错误如何解决?

问题现象描述

当开发者使用RandomUnderSampler处理类别不平衡数据时,经常会遇到如下报错:

ValueError: Expected n_neighbors <= n_samples, 
but n_samples = 5, n_neighbors = 6

这个错误通常发生在少数类样本数量极少的情况下,特别是在配置RandomUnderSampler时启用了k_neighbors参数或使用某些特定采样策略时。

错误原理分析

该错误的根本原因在于样本数量与邻域参数的冲突

  1. 当少数类样本数量小于n_neighbors参数时,K近邻算法无法计算有效邻域
  2. RandomUnderSampler内部某些版本会默认调用KNN进行样本验证
  3. 数据集经过前期预处理后可能导致某些类别样本数骤减

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)