log_loss直接计算预测概率与真实标签的交叉熵,要求y_true为一维整数标签、y_pred为行和为1的概率矩阵,类别顺序必须严格对齐,否则结果不可信。

log_loss 直接计算的是模型预测概率与真实标签之间的交叉熵,不是简单“预测对错”的惩罚;它要求输入必须是概率矩阵(非 one-hot 标签),且所有样本的预测概率行和必须为 1。
log_loss 的输入格式必须严格满足:y_true 是整数标签,y_pred 是二维概率数组
常见错误是把 y_true 写成 one-hot 编码(如 [[1,0],[0,1]])或把 y_pred 写成类别索引(如 [0,1])。log_loss 会静默报错或返回意外值。
-
y_true应为一维整数数组,例如[0, 1, 2, 1](对应 3 分类) -
y_pred必须是二维numpy.ndarray,形状为(n_samples, n_classes),每行是归一化后的预测概率,例如[[0.8,0.1,0.1], [0.2,0.7,0.1], ...] - 如果用
predict_proba得到输出,通常已合规;但若用decision_function或手工拼接,需手动softmax或sigmoid归一化
多分类时 label 的顺序必须与 y_pred 的列顺序严格一致
log_loss 不推断类别语义,只按位置匹配。若训练时 LabelEncoder 编码后类别顺序是 ['cat', 'dog', 'bird'] → [0,1,2],那么 y_pred[:, 0] 就必须对应 'cat' 的预测概率。
- 用
model.classes_检查实际类别顺序(对LogisticRegression、RandomForestClassifier等有效) - 若
y_pred来自不同模型或预处理流程,务必确认列索引与y_true数值标签对齐,否则损失值完全不可信 - 不建议依赖
sorted(set(y_true))推断顺序——scikit-learn 默认按升序,但显式传入labels=[...]参数更安全
遇到 “ValueError: y_true and y_pred contain different number of classes” 怎么办
这个错误不是因为类别总数不同,而是指 y_true 中出现的类别数 ≠ y_pred.shape[1],或者 y_true 含有未在训练中见过的标签(比如测试集混入新类别)。
立即学习“Python免费学习笔记(深入)”;
- 检查
len(set(y_true)) == y_pred.shape[1],不等就说明漏类或冗余列 - 若
y_true是从原始字符串标签转换而来,确认没漏掉fit过的LabelEncoder或OneHotEncoder - 允许跳过缺失类:加参数
labels=sorted(set(y_true)),强制限定类别集合 - 极小概率下,某类在
y_true中只出现一次且y_pred对应列为全 0,会触发log(0)→inf;此时可加eps=1e-15防止数值溢出(默认已启用)
真正容易被忽略的是:log_loss 对低置信度错误极其敏感,一个 [0.01, 0.99] 预测错标为 0,贡献的损失接近 4.6;而同样错误若预测为 [0.4, 0.6],损失仅约 0.92。所以它不只是评估“准不准”,更是评估“有多确信地错了”。


















