计算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]])