多类分类和 log_loss

数据挖掘 分类 scikit-学习 损失函数 f1score
2022-03-12 07:36:58

我希望我可以用几行代码/解释来说明这一点。

我有一个 16K 的文本列表,标记了 30 多个通过不同分类器运行的不同类别;我的预测和地面实况平均匹配率为 94%。

我现在在测量一些额外的东西之后(不确定我应该在 F1_score 最小值之上测量什么,因为我仍在学习,但我遇到了来自 sklearn 的 log_loss,结果我理解它的范围在 0 和 1 之间。当然而,结果与我的预测相反,结果是 1.48xxx,实际上更高。

在试图了解什么是错的。

我已经探索了 log_loss 所需的 ComplementNB.predict_proba 的结果,并且该值与我的预测数组之一匹配。

下面是一些代码:

from sklearn.metrics import log_loss

y = ... # This is my array of value that is my source of truth

labels = numpy.unique(y)
label_ary = [idx for gt in y for idx, lbl in enumerate(labels) if gt == lbl]

print(f'The log loss is {log_loss(label_ary, clf.predict_proba(X.toarray()))}')

无论我使用 label_ary 还是 y,在这两种情况下我都获得了相同的值,这意味着 log_loss 中的某些转换已经发生。

我不确定是我误解了结果还是函数的具体含义。

我究竟做错了什么?谢谢

1个回答

日志丢失的可解释性

对数损失不一定在 [0; 1] - 它只期望输入在这个范围内。看看这个例子: 在极端情况下,日志损失甚至可以等于无穷大。因此,代码没有任何问题,而且从 log_loss 小于或大于 1 的事实中您可以得出的有趣的东西并不多。您可以用它做的事情与任何损失函数相同 - 将其与具有不同超参数的类似模型,并选择平均损失最低的模型作为最佳模型(称为超参数优化的过程)。

ypred=0.1ytrue=1.0log_loss=(log(ypred)ytrue+(1ytrue)log(1ypred))=(log(0.1)1.0)=2.302

何时使用损失以及何时使用 f1 得分?

假设您有一个数据集和一个要解决的分类问题。你知道你可以创建一个统计模型来返回给定类的概率。您还知道(假设地)有一种算法可以根据一些不需要训练的启发式方法进行分类。您想知道其中哪一个最适合您的问题。如果我们稍微简化一下,您所做的是:

  1. 将数据集拆分为训练集、验证集和测试集。
  2. 使用您的训练集训练模型
  3. 在训练模型时,计算每个 epoch 中训练集和验证集的损失(如果你不使用深度神经网络,你可以并且应该使用交叉验证)。
  4. 绘制训练集和验证集的损失,并查看您的模型是否存在偏差(高训练损失和高验证损失)或过度拟合(低训练损失和高验证损失)。验证集的损失越低越好。
  5. 对不同的超参数执行 3. 和 4. 多次,并选择一个具有最低验证集损失的参数。您现在拥有一个训练有素的统计模型。
  6. 现在使用 f1 score 将您的模型与您也知道的算法进行比较。分数越高越好。请注意,假设算法返回类而不是概率,即使对于一个示例也不正确,它的对数损失函数将等于无穷大。这就是为什么我们不能使用日志损失作为衡量这两种方法的指标。

简而言之,您应该在训练/验证过程中使用损失作为指标,以在测试过程中优化参数和超参数以及 f1 分数(可能还有更多指标,例如曲线下面积),以选择解决问题的最佳方法。这样就可以比较不同的方法来解决问题——即使是根本不使用机器学习的方法。