应使用imblearn而非sklearn做重采样,因其自动保证X与y同步变换、支持random_state控制随机性,并提供SMOTE等专业方法;慎用SMOTE处理高维稀疏数据,关键参数包括sampling_strategy和k_neighbors。

用 imblearn 而不是 sklearn 做重采样
Scikit-learn 本身不提供重采样(oversampling/undersampling)工具,硬要用 sklearn.utils.resample 手动实现容易漏掉标签对齐、随机种子一致性或分层逻辑。实际项目中应直接上 imbalanced-learn(imblearn),它是 scikit-learn 兼容的专用扩展库。
安装命令:
pip install imbalanced-learn
常见错误现象:用 sklearn.utils.resample 对 X 和 y 分别重采样,结果样本顺序错位,训练时特征和标签不匹配。
- 必须用
imblearn.over_sampling.SMOTE或imblearn.under_sampling.RandomUnderSampler等类,它们自动保证X和y同步变换 - 所有采样器都支持
random_state参数,务必设固定值,否则交叉验证时每次重采样结果不同,评估不可靠 - 慎用
SMOTE处理高维稀疏数据(如文本 TF-IDF),易生成噪声样本;可改用imblearn.over_sampling.ADASYN或先降维
SMOTE 的关键参数怎么调?
SMOTE 默认只对少数类过采样到与多数类等量,但实际中往往不需要“完全平衡”。盲目拉平可能引入过拟合或掩盖真实分布偏移。
立即学习“Python免费学习笔记(深入)”;
核心参数说明:
-
sampling_strategy:控制目标比例,可传 float(如0.5表示少数类样本数达到多数类的 50%),或 dict(如{0: 100, 1: 200}指定各类最终数量) -
k_neighbors:生成新样本时参考的最近邻数,默认为 5;类别极少(如每类 ValueError: Expected n_neighbors -
random_state:必须设置,否则 pipeline 中无法复现
示例:
from imblearn.over_sampling import SMOTE<br>smote = SMOTE(sampling_strategy=0.3, k_neighbors=3, random_state=42)<br>X_res, y_res = smote.fit_resample(X_train, y_train)
重采样该放在 Pipeline 里还是外面?
必须放进 imblearn.pipeline.Pipeline,不能在训练前单独对全量 X_train 调用 fit_resample。
原因很直接:如果在 cross-validation 外预处理,验证折里的少数类样本会被泄露到训练折的合成样本中,导致评估指标虚高——这属于数据穿越(data leakage)。
- 用
imblearn.pipeline.Pipeline替代sklearn.pipeline.Pipeline,它能正确处理重采样步骤的 fit/transform 时机 - 重采样器只能出现在 Pipeline 的早期(如第 1 步),不能放在标准化或特征选择之后——因为 SMOTE 是基于原始特征空间插值的
- 若 Pipeline 中含
StandardScaler,务必让它在重采样器之后,否则合成样本会受 scaler 影响失真
比重采样更稳的选择:代价敏感学习
当数据量大、重采样耗时高,或业务上明确要求“宁可漏判也不误判”(如金融风控),直接用代价敏感方法更可靠。
scikit-learn 原生支持,无需额外库:
-
LogisticRegression、SVC、RandomForestClassifier都有class_weight参数 -
class_weight="balanced"等价于自动设weight = n_samples / (n_classes * n_samples_in_class) - 更精细控制可用
class_weight={0: 1, 1: 5},数值越大表示越不愿将该类预测错 - 注意:
class_weight不改变训练集分布,只调整损失函数梯度权重,因此不会放大噪声或过拟合风险
性能提示:对树模型(如 RandomForestClassifier),class_weight 比 SMOTE 快一个数量级,且天然兼容 CV。
真正棘手的是多分类 + 极端不平衡(比如 100 类中 99 类各只有 1–2 个样本),这时单靠 SMOTE 或 class_weight 都难奏效,得结合异常检测、主动学习或分层抽样策略——但那是另一层问题了。


















