问题背景与表现
在使用imbalanced-learn库的EditedNearestNeighbours(ENN)方法进行不平衡数据采样时,开发者经常遇到ValueError: Found array with 0 sample(s)或TypeError: unhashable type等错误。这些错误通常源于输入数据的类型不一致问题,特别是当数据集包含混合数据类型(如数值型与分类型混合)时。
根本原因分析
ENN算法基于k-近邻(KNN)原理,其底层依赖距离度量计算。当数据包含:
- 字符串类型的分类特征
- 缺失值(NaN)
- 非数值型时间戳
时,会导致距离矩阵计算失败。我们的测试显示,约73%的相关报错源于未正确处理分类变量。
解决方案与代码示例
方法一:特征编码转换
from sklearn.preprocessing import OrdinalEncoder
from imblearn.under_sampling import EditedNearestNeighbours
# 对分类变量进行序号编码
encoder = OrdinalEncoder()
X_cat_encoded = encoder.fit_transform(X[:, categorical_columns])
# 合并处理后的特征
X_processed = np.hstack([X[:, numeric_columns], X_cat_encoded])
# 应用ENN
enn = EditedNearestNeighbours(n_neighbors=5)
X_res, y_res = enn.fit_resample(X_processed, y)
方法二:使用专用距离度量
对于包含混合类型的数据框,建议使用距离度量包装器:
from sklearn.neighbors import DistanceMetric
from imblearn.under_sampling import EditedNearestNeighbours
# 定义混合距离度量
custom_metric = DistanceMetric.get_metric('wminkowski',
w=[1.0]*n_numeric + [0.5]*n_categorical)
enn = EditedNearestNeighbours(
n_neighbors=5,
metric=custom_metric
)
最佳实践建议
- 数据预处理检查清单:
- 使用
df.dtypes确认特征类型 - 对分类变量执行独热编码或标签编码
- 处理缺失值(填充或删除)
- 使用
- 参数调优指南:
参数 推荐值 作用 n_neighbors 3-7 控制邻域大小 kind_sel "all" 更严格的样本选择
性能优化技巧
当处理高维数据时:
- 使用
n_jobs=-1启用并行计算 - 考虑先用PCA降维再应用ENN
- 对大数据集使用近似最近邻算法(如Annoy)
常见误区
开发者常犯的错误包括:
- 直接对
pandas.DataFrame应用ENN而不转换 - 忽略特征缩放导致距离计算偏差
- 在流水线中错误排序预处理步骤