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
得到正值。