You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

手动计算Log Loss与Scikit-Learn cross_val_score结果不符问题

Scikit-Learn cross_val_score与手动Log Loss计算不一致的原因及解决

核心问题

你手动计算Log Loss时用了predict()返回的类别标签,而log_loss函数需要的是模型输出的概率值,这和cross_val_score内部计算neg_log_loss的逻辑完全不同。

具体差异

  • 你的手动代码中,y_train_pred = clf_logreg.predict(X_train)返回的是离散的类别(0或1)。当把这类标签代入log_loss时,相当于强制将概率设为1(对应预测类别)或0(非预测类别),一旦样本预测错误,log(0)会被近似为极大的负值,最终损失值被大幅拉高,这就是你看到的train_loss和val_loss远高于cross_val结果的原因。
  • cross_val_score使用scoring='neg_log_loss'时,内部会自动调用模型的predict_proba()方法,获取每个样本属于各类别的概率分布(比如二分类场景下返回[[1-p, p], ...]),再基于这些概率计算对数损失,这才是log_loss的正确使用方式。

修正后的手动计算代码

把predict()替换为predict_proba(),并提取对应类别的概率(以二分类为例,取正类概率[:, 1]):

kfold = KFold(n_splits=10)
train_loss = []
val_loss = []

for train_index, val_index in kfold.split(X, y):
    clf_logreg = LogisticRegression()
    
    X_train, X_val = X[train_index], X[val_index]
    y_train, y_val = y[train_index], y[val_index]
    
    clf_logreg.fit(X_train, y_train)
    
    # 替换predict为predict_proba,取正类概率
    y_train_pred_proba = clf_logreg.predict_proba(X_train)[:, 1]
    y_val_pred_proba = clf_logreg.predict_proba(X_val)[:, 1]
    
    train_loss.append(log_loss(y_train, y_train_pred_proba))
    val_loss.append(log_loss(y_val, y_val_pred_proba))    
    
clf_logreg.fit(X,y)
y_error = cross_val_score(clf_logreg, X, y, cv=kfold, scoring='neg_log_loss')

print("cross_val log_loss: ", -y_error)
print("\ntrain_loss: ", train_loss)
print("\nval_loss: ", val_loss)

修正后,手动计算的val_loss会和cross_val log_loss的结果一致(误差在浮点精度范围内)。

内容的提问来源于stack exchange,提问作者Ulisses Morais

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 13:55:17