sklearn logloss计算

计算logloss函数sklearn.metrics._classification.log_loss 方法签名:

def log_loss(y_true, y_pred, eps=1e-15, normalize=True, sample_weight=None,
             labels=None):

参数 y_true,也就是测试集的标签列数据,
参数 y_pred, 是模型对测试集的预测分数。

如果模型的预测分数(model.predict_proba) 结果为:

[[0.1, 0.3, 0.6],
 [0.1, 0.6, 0.3]]

对应的测试集的标签为:

['dog', 'cat']

来计算logloss:

from sklearn import metrics
y_score = [[0.1, 0.3, 0.6],
 [0.1, 0.6, 0.3]]
y_test = ['dog', 'cat']
metrics.log_loss(y_true=y_test, y_pred=y_score)

执行后报错:

ValueError: y_true and y_pred contain different number of classes 2, 3. Please provide the true labels explicitly through the labels argument. Classes found in y_true: ['cat' 'dog']

y_score 中的概率传给logloss函数,它并不知道每个概率对应的label是什么,例如不知道第一组概率 [0.1, 0.3, 0.6] 是对应 标签 ['dog', 'cat', 'children']还是[ 'cat', 'dog', 'children'],仅知道概率,不知道是哪个概率无法得知模型的预测结果,进而也就无法评估。

其方法中有一个参数labels 可以用来指定概率对应的标签:

metrics.log_loss(y_true=y_test, y_pred=y_score, labels=['dog', 'cat', 'children'])

如果根据模型中的标签列的信息(model.classes_),来排列y_test,使之与y_score对应,也可以进行计算:

from sklearn.preprocessing import label_binarize
# label_binarize 先对y_test按照classes的顺序转换成数字, 比如'dog'在classes中的位置是0,转换为0,然后初始化长度为3的数组,第0个位置置为1,得到[1,0,0], 其概率也是按照classes输出的,这样就能对应了
y_test_onehot = label_binarize(y_test, classes=['dog', 'cat', 'children'])  # 多分类模型大多都有classes_属性
metrics.log_loss(y_test_onehot, y_score)
y_test_onehot

输出:

array([[1, 0, 0],
       [0, 1, 0]])
原文地址:https://www.cnblogs.com/oaks/p/14230750.html