具有 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
参数更改函数内的“正”标签索引,但如果出于约定/绝大多数库都是使用这种假设实现的。
我正在从这个 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
参数更改函数内的“正”标签索引,但如果出于约定/绝大多数库都是使用这种假设实现的。