具有 f1、精度和召回分类的变形金刚 longformer 分类问题

transformers longformer classification problem with f1, precision and recall classification

我正在从这个 page 复制代码,我得到的 F1、准确率和召回率都为 0。我得到了作者所展示的准确率。可能是什么原因?

我查看了 compute_metrics 函数,它似乎是正确的。我尝试了一些玩具数据如下,precision_recall_fscore_support 似乎给出了正确答案

from sklearn.metrics import accuracy_score, precision_recall_fscore_support

y_pred = [1, 1, 2]
y_true = [1, 2, 2]
print (accuracy_score(y_true, y_pred))

precision_recall_fscore_support(y_true, y_pred, average='binary')


0.6666666666666666
(0.5, 1.0, 0.6666666666666666, None)

因为我得到了准确性,所以下面的部分似乎按预期工作

labels = pred.label_ids
preds = pred.predictions.argmax(-1)

acc = accuracy_score(labels, preds)

我猜你的因变量的转换不知何故搞砸了。 我认为这是因为你所有依赖于 TP (True Posivites) 的指标都是 0 ->

精度灵敏度(召回率)都取决于 TP 作为分子:

Precision = TP / (TP + FP)
Sensitivity = TP / (TP + FN)

F1-Score 取决于两个指​​标,因此取决于 TP 作为分子:

F1-Score = 2(Precision*Sensitivity)/(Precision+Sensitivity)
         = TP / (TP + 1/2(FN+FP))

->如果分子为0,因为你没有TP,结果也为0!

一个good/moderate如果你只把TN选对了也能达到准确率:

Accuracy = (TP + TN) / Total

这就是为什么您可以获得有效的外观准确度而其他指标为 0 的原因。

所以请查看您的 test/training 集合,看看拆分是否成功,以及是否 您的二元变量 的两种可能结果在两个集合中都可用!如果训练集中缺少其中一个,这可能会解释 test-set.

中的完全错误分类和缺少 TP

一段解释颜色,跳到第2段回答:precision、recall、F1是二元指标,即它们对二元分类问题有意义,但更具体地说,当你想预测存在或缺少单个属性。此类指标可能有用的一个典型问题是将患者数据分类为癌性(阳性)或 non-cancerous(阴性)。在这种情况下,精确度是有意义的(你预测得癌症的例子中有多少实际上得了癌症?)而召回率是有意义的(在癌症的例子中,你抓到的比例是多少?)。精度/召回率对于两个同等重要的分类类(例如,红色和绿色)之间的二元或多类分类问题用处不大。在这种情况下给出精确度的用处不大,因为精确度是针对特定标签的。例如,根据您的计算方式,精度可能意味着(我说是红色的示例的比例,实际上是红色的)或(我说是绿色的示例的比例,实际上是绿色的)。尚不清楚应将这些标签中的哪些视为主要标签,因此该指标在这种情况下用处不大。

所有这些都是迂回的说法,在 sklearn 中实现的精度和召回率默认情况下期望使用单个二进制属性。 此类二元分类问题的惯例是使用 0 表示负属性标签,使用 1 表示正属性标签。默认情况下,函数会这样。

因此,您在二元分类问题中使用 [1,2] 而不是 [0,1] 标签具有误导性,并且这些函数进行的计算与您预期的不同。作为一个简单的例子:

  from sklearn.metrics import accuracy_score, precision_recall_fscore_support

  y_pred = [0, 0, 1]
  y_true = [0, 1, 1]
  print (accuracy_score(y_true, y_pred))

  precision_recall_fscore_support(y_true, y_pred, average='binary')

  # Result
  >>> 0.6666666666666666
  >>> (1.0, 0.5, 0.6666666666666666, None)
  
  # Using your original labels 

  y_pred = [1, 1, 2]
  y_true = [1, 2, 2]
  print (accuracy_score(y_true, y_pred))

  precision_recall_fscore_support(y_true, y_pred, average='binary')

  # Result
  >>> 0.6666666666666666
  >>> (0.5, 1, 0.6666666666666666, None)

虽然您可以使用 pos_label 参数更改函数内的“正”标签索引,但如果出于约定/绝大多数库都是使用这种假设实现的。