sklearn logloss scorer (neg_log_loss) 计算为负数的问题

在使用sklearn 的logloss scorer时候,发现分数计算是个负数,例如:

from sklearn.metrics import log_loss
import numpy as np
from sklearn.metrics import get_scorer

y_true = np.array([1,1,0,1]).reshape((4, 1))
y_proba = np.array([[0.2, 0.8], [0.1, 0.9], [0.9, 0.1], [0.3, 0.7]]).reshape((4,2))


class MyEstimator:
    def __init__(self):
        self.classes_ = np.array([0, 1])

    def predict_proba(self, X, **kwargs):
        return  np.array([[0.2, 0.8], [0.1, 0.9], [0.9, 0.1], [0.3, 0.7]]).reshape((4,2))

    def predict(self, X, **kwargs):
        return np.array([1,1,0,1]).reshape((4,1))

neg_log_loss_scorer = get_scorer('neg_log_loss')
neg_log_loss_scorer(estimator=MyEstimator(), X=y_proba, y_true=y_true)
# output
# -0.19763488164214868

输出的分数是-0.19763488164214868, logloss 的计算方式:
\( logloss = -ln[p(y|X,w)] = \sum_{i=1}^N[-ln(a_i^{y_i}) - ln(1-a_i)^{1-y_i}] \)

其中:
\(a_i = a(x_i|w)\)

因为 \(a_i^{y_i} \in [0,1]\) 所以, logloss 的取值应该是 \([0, +\infin]\) (不归一化) ,是个非负数,并且越小越好。

手动进行计算:

-(np.log(0.8) + np.log(0.9) + np.log(0.9) + np.log(0.7)) / 4
#output
#0.19763488164214868

发现sklearn scorer 计算的结果是加了负号,使用sklearn logloss metric进行计算:

from sklearn.metrics import log_loss
log_loss(y_true, y_pred=y_proba)
#output
#0.19763488164214868

这个结果与手动计算的结果一样。

后来发现sklearn 的 logloss scorer 定义为:

neg_log_loss_scorer = make_scorer(log_loss, greater_is_better=False, needs_proba=True)

它指定了greater_is_better=False, 会给计算结果加上负号,为了给优化器用,
让这个分数越大越好,它的变量名字可以看出来 neg_log_loss_scorer ,是加了负号的logloss。如果希望就是原生的logloss,可以设置greater_is_better=True得到正值。

posted @ 2023-03-13 16:05  oaksharks  阅读(175)  评论(0编辑  收藏  举报