class_weight='balanced'不能解决样本不均衡问题,因其仅影响单棵树的分裂,而随机森林投票仍为等权;应改用'balanced_subsample'或imblearn的balancedrandomforestclassifier。

为什么 class_weight='balanced' 不能直接解决你的样本不均衡问题
很多人以为给 RandomForestClassifier 加上 class_weight='balanced' 就万事大吉,结果发现 F1-score 没提升、少数类召回率依然很低。这是因为该参数只作用于每棵决策树的基学习器(即每个 DecisionTreeClassifier 的 fit 过程),但随机森林本身不加权聚合预测——投票仍是“一人一票”,不是“按权重投票”。所以即使单棵树更关注少数类,最终集成仍可能被多数类主导。
正确做法:用 class_weight='balanced_subsample' + 手动控制采样逻辑
这是 Scikit-learn 原生支持、且最贴近“带权重平衡的随机森林”的方案。它在每次构建子树时,对当前 bootstrap 样本重新计算类别权重,并用于该树的分裂过程。相比 'balanced',它更动态、更适配 bagging 的随机性。
-
class_weight='balanced_subsample'是唯一被RandomForestClassifier显式支持的采样级权重策略 - 必须配合
bootstrap=True(默认值),否则无效 - 不要同时设置
sample_weight参数,二者冲突;如需自定义采样逻辑,应改用imblearn.ensemble.BalancedRandomForestClassifier - 示例用法:
from sklearn.ensemble import RandomForestClassifier<br>clf = RandomForestClassifier(class_weight='balanced_subsample', random_state=42)
当 balanced_subsample 仍不够用时,换用 imblearn 的 BalancedRandomForestClassifier
如果你需要更强的平衡能力(比如强制每棵树训练集里各类样本数严格相等),imblearn 提供了更底层的控制。它本质是:每轮 bootstrap 后,对多数类做随机欠采样,使当前子样本中各类数量一致,再训练单棵树。
- 安装:
pip install imbalanced-learn - 接口与原生
RandomForestClassifier高度兼容,但多了sampling_strategy和replacement等参数 - 注意:它不支持
class_weight参数,所有平衡逻辑由采样阶段完成 - 常见误用:
sampling_strategy='not majority'表示只对非多数类过采样(慎用,易过拟合);推荐保持默认'auto'(即欠采样多数类)
验证时别只看 accuracy,必须检查 classification_report 中的 minority class
模型输出看起来“准确率 95%”很诱人,但如果测试集里 95% 是负样本,那全猜负就达标了。真正关键的是少数类的 recall 和 f1-score。
- 务必用
sklearn.metrics.classification_report(y_true, y_pred),观察最后一行(通常是少数类) - 如果用
cross_val_score,评分函数必须指定scoring='f1_macro'或'recall_macro',而非默认'accuracy' - 混淆矩阵里
tn/fp很大但fn也很大?说明模型仍在忽略少数类——这时要回头检查是否误用了class_weight='balanced'而非'balanced_subsample'
balanced_subsample,单棵树也可能根本学不到有效模式——这时候得先考虑业务层面的数据补充或合成样本(如 SMOTE),而不是只调模型参数。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











