该用SMOTE+RandomUnderSampler组合时:少数类样本50–500、特征维度

什么时候该用 SMOTE + RandomUnderSampler 组合
单独用 SMOTE 容易让少数类过拟合边界噪声,尤其在高维稀疏特征或类别重叠严重时;只用 RandomUnderSampler 又可能丢掉多数类关键分布信息。混合策略适合:少数类样本量在 50–500 之间、特征维度中等(
- 先过采样再欠采样是主流顺序,因为
SMOTE生成的新样本需要被后续欠采样“筛选”一次,避免冗余 - 切忌反过来:先欠采样会缩小多数类分布范围,再用
SMOTE插值可能加剧类间混淆 - 目标采样比例建议设为
0.7–0.9(少数类:多数类),而非强行 1:1——真实业务中 1:1 往往导致阈值偏移和线上 F1 下降
用 imblearn 实现 SMOTE + RandomUnderSampler 的关键参数
核心是用 imblearn.pipeline.SMOTEENN 或手动串起两个步骤。推荐手动组合,便于调试中间状态:
from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import RandomUnderSampler
from imblearn.pipeline import Pipeline
<p>smote = SMOTE(sampling_strategy=0.6, k_neighbors=3, random_state=42)
rus = RandomUnderSampler(sampling_strategy=0.8, random_state=42)
pipeline = Pipeline([('smote', smote), ('rus', rus)])
X_res, y_res = pipeline.fit_resample(X_train, y_train)</p>
-
sampling_strategy是比例(float)而非数量,0.6 表示最终少数类占多数类的 60%,不是总样本的 60% -
k_neighbors=3是安全起点;若数据噪声多,可降到 2;若边界清晰,可试 5,但超过 5 易引入离群插值 -
RandomUnderSampler的sampling_strategy必须 ≤SMOTE输出后的多数类比例,否则 pipeline 会报ValueError: After over-sampling, the number of samples...
验证混合采样是否真有效,别只看训练集准确率
训练集上准确率飙升但验证集 F1 不动,大概率是过采样引入了不可泛化的合成样本。必须检查:
- 每个采样步骤前后,用
np.bincount(y_train)打印各类样本数,确认没意外翻转主次类 - 在
SMOTE后、RUS前,用TSNE可视化前两维,观察合成点是否大量落在多数类簇内部(说明插值失效) - 用
sklearn.metrics.classification_report对验证集输出 per-class precision/recall/f1,重点关注少数类的precision是否同步提升——如果 recall↑ 但 precision↓,说明混入了太多假阳性样本
比 pipeline 更稳的替代方案:使用 SMOTETomek
SMOTETomek 内部先用 SMOTE 过采样,再用 TomekLinks 清洗邻近异类样本对,本质是“过采样 + 边界净化”,比随机欠采样更尊重原始分布:
from imblearn.combine import SMOTETomek smt = SMOTETomek(sampling_strategy=0.7, random_state=42) X_res, y_res = smt.fit_resample(X_train, y_train)
-
TomekLinks会自动删掉那些“彼此最近却属于不同类”的样本对,这对去除边界噪声特别有效 - 计算开销比
SMOTE + RUS高约 2–3 倍,但在小数据集( - 如果你发现
SMOTE + RUS后验证集 AUC 波动大,优先换SMOTETomek,而不是调参
实际项目里,采样策略的效果高度依赖特征工程质量。没做标准化就跑 SMOTE,合成点方向会严重偏向量纲大的特征;类别标签本身有标注噪声时,任何过采样都在放大错误。先确保特征干净、标签可信,再调采样器。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











