class_weight="balanced"按公式n_samples/(n_classes×n_samples_in_class)计算各类权重,使稀有类损失贡献放大;键必须匹配真实标签类型,与sample_weight相乘叠加,CV中需在模型构造时传入。

class_weight="balanced" 是怎么算出来的
它不是简单按类别频次倒数缩放,而是用 n_samples / (n_classes * n_samples_in_class) 公式自动计算每个类的权重。比如训练集共 1000 条样本,其中正类 50 条、负类 950 条,那么正类权重是 1000 / (2 * 50) = 10.0,负类是 1000 / (2 * 950) ≈ 0.526。这个机制本质是让稀有类的损失贡献被放大,从而推动模型更关注少数类。
手动传入字典时 key 必须是真实标签值
如果你的标签是字符串(如 "spam" 和 "ham"),class_weight 字典就得写成 {"spam": 10, "ham": 1};如果是整数标签(如 0 和 1),就必须用 {0: 10, 1: 1}。传错类型或键不存在会直接报错:ValueError: Class label not found。
常见错误包括:
- 用
{1: 10, 0: 1}但实际标签是["A", "B"] - 标签含
np.nan或未去重,导致字典 key 不全 - 训练前做了
LabelEncoder,但没同步更新class_weight字典的 key
和 sample_weight 混用时优先级关系
class_weight 在拟合前就转换为内部的 sample_weight,所以它和显式传入的 sample_weight 参数是相乘关系。也就是说,最终每个样本的权重 = class_weight[标签] × sample_weight[i]。
这意味着:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 如果同时设了
class_weight="balanced"和自定义sample_weight,效果不是“二选一”,而是叠加 - 当你要对某几个难分样本额外加权时,得先确认
class_weight已经拉高了整个类的基线权重,再微调个别样本 - 调试时建议先固定
class_weight,单独验证sample_weight的影响,避免干扰源太多
别忽略 cross-validation 中的 class_weight 传递
用 sklearn.model_selection.cross_val_score 或 GridSearchCV 时,class_weight 必须通过 estimator 构造时传入,不能在 fit() 阶段临时加——因为 CV 会反复新建模型实例。
正确写法是:
from sklearn.linear_model import LogisticRegression from sklearn.model_selection import cross_val_score <p>lr = LogisticRegression(class_weight="balanced") # ✅ 这里传 scores = cross_val_score(lr, X, y, cv=5, scoring="f1")</p>
错误写法是:
# ❌ 下面这行不会生效:cv 过程中每个 fold 都会重新 init LogisticRegression,不带 class_weight
cross_val_score(LogisticRegression(), X, y, cv=5, fit_params={"class_weight": "balanced"})
另外注意:class_weight="balanced" 是按**每次 CV fold 的训练子集**独立计算的,不是用全量数据算一次再复用。这点在小数据集上会导致 fold 间权重波动较大。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










