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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章