【问题标题】:Calculate F1-score in a Named Entity Recognition model with sklearn使用 sklearn 在命名实体识别模型中计算 F1 分数
【发布时间】:2022-01-16 03:00:13
【问题描述】:

我正在尝试验证对某些数据执行命名实体识别的 ML 模型。 我的问题与 F1-Score 的计算方式有关。我正在使用来自 sklearn 的分类报告

print(preds[:2],labels[:2])

#output: [[5, 5, 5, 5, 5, 5, 5, 5, 1],[6, 2]]  [[1, 5, 5, 5, 5, 5, 5, 5, 5, 5],[6, 2]]

这里我们有真实的标签 Ids 和预测的 Ids。正如我们所见,第一个标签不同,即在预测中它的值为“1”,但是在标签中它的值为“5”。在我看来,这意味着令牌被错误地分类。 接下来,为了使用 sklearning 指标,我们必须使用 MultiLabelBinarizer 中的 fit_transform 转换我们的数组,因为我们有超过 2 个标签。

transformed_labels = MultiLabelBinarizer().fit_transform(labels)
transformed_preds = MultiLabelBinarizer().fit_transform(preds)
print(transformed_preds [:2],transformed_labels [:2])

#output: [[1 0 0 1 0],[0 1 0 0 1]]  [[1 0 0 1 0],[0 1 0 0 1]] 

这是我不明白的部分。此方法只保存每个序列中使用了哪些实体,而不关心标签的任何顺序或数量。

labels = ['Date','Place','Org','Person','Event']
    print(classification_report(transformed_labels ,transformed_preds ,target_names=labels))

              precision    recall  f1-score   support

        Date       0.69      0.92      0.82       122
       Place       0.90      0.94      0.93       195
         Org       0.76      0.85      0.78        79
      Person       0.99      0.98      0.98       434
       Event       0.81      0.69      0.73        55

最后,指标相当高,但我不认为它们是准确的,因为它们仅基于预测序列是否在真实序列中至少出现每个实体的情况来计算。

我看错了吗?

我看到的另一种方法:

def calc_precision(pred, true):
    precision = len([x for x in pred if x in true]) / (len(pred) + 1e-20) # true positives / total pred
    return precision

在这里,我们正在计算 pred 列表相对于真实列表的精度。

为此,该函数仅检查预测标签是否在真实标签列表中。同样,没有考虑出现次数和顺序。

在 NER 中计算 F1 分数的正确方法是什么?

【问题讨论】:

    标签: python validation machine-learning scikit-learn named-entity-recognition


    【解决方案1】:

    我接受您为您的数据集使用 IOB2 标记方案,并继续考虑这个方案来回答。 由于严格匹配类型和边界在 NER 中很重要,您可以将预测输出和真实标签调整为列表列表并使用Seqeval Library

    一个玩具例子使用它的例子如下:

    from seqeval.metrics import f1_score
    y_true = [['B-PER', 'I-PER', 'O'], ['O', 'O', 'B-LOC']]
    y_pred = [['B-PER', 'O', 'O'], ['O', 'O', 'B-LOC']]
    f1_score(y_true, y_pred)
    

    考虑到玩具示例,f1 分数应为 0.5,因为 PER 实体没有正确预测其边界,而 LOC 实体被正确预测。

    【讨论】:

      【解决方案2】:

      您可以使用 f1 分数进行验证。除非您正在进行多标签分类,否则您可以直接调用该函数。 如果您解释为什么 preds 中有 2 个列表,这将很容易提供帮助, 你可以参考这个文档 https://scikit-learn.org/stable/modules/generated/sklearn.metrics.f1_score.html

      【讨论】:

      • 感谢您的回复。如您所见,我有 5 个标签,所以我必须进行多标签分类。至于 preds,每个列表代表一个句子。这里我只打印了前两个句子以简化“preds[:2]”。 preds 和 label 都有多个列表,表示所有预测和真实标签句子。我已经尝试直接使用 F1 分数,但我的问题仍然存在,因为我还必须进行 MultiLabelBinarizer 转换。
      猜你喜欢
      • 2017-05-07
      • 2017-09-11
      • 2018-03-26
      • 2013-02-21
      • 2010-11-04
      • 2015-01-11
      • 1970-01-01
      • 2010-12-19
      • 1970-01-01
      相关资源
      最近更新 更多