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