在命名实体识别中计算精度和召回率

Posted

技术标签:

【中文标题】在命名实体识别中计算精度和召回率【英文标题】:Computing precision and recall in Named Entity Recognition 【发布时间】:2010-12-19 12:17:18 【问题描述】:

现在我要报告命名实体识别的结果。我觉得有点令人困惑的一件事是,我对精确率和召回率的理解是简单地总结所有类别的真阳性、真阴性、假阳性和假阴性。

但是现在我认为这似乎不可信,因为每个错误分类都会同时产生一个误报和一个误报(例如,应该标记为“A”但被标记为“B”的标记是“A”为假阴性,“B”为假阳性)。因此,所有类别的误报和误报的数量将是相同的,这意味着精度(总是!)等于召回。这根本不可能是真的,所以我的推理有误,我想知道它在哪里。这当然是非常明显和直截了当的事情,但现在我却无法理解。

【问题讨论】:

【参考方案1】:

通常计算精度和召回率的方式(这是我在论文中使用的)是衡量实体之间的对比。假设基本事实具有以下内容(对于它们是什么类型的实体没有任何区别)

[Microsoft Corp.] CEO [Steve Ballmer] announced the release of [Windows 7] today

这有 3 个实体。

假设您的实际提取具有以下内容

[Microsoft Corp.] [CEO] [Steve] Ballmer announced the release of Windows 7 [today]

Microsoft Corp 完全匹配,CEOtoday 有误报,Windows 7 有误报,Steve 有子字符串匹配

我们通过首先定义匹配标准来计算精度和召回率。例如,它们是否必须完全匹配?如果它们完全重叠,是否匹配?实体类型重要吗?通常,我们希望为其中几个标准提供精确度和召回率。

完全匹配:真阳性 = 1(Microsoft Corp.,唯一的完全匹配),假阳性 =3(CEOtodaySteve,这不是完全匹配),假阴性 = 2(Steve BallmerWindows 7

Precision = True Positives / (True Positives + False Positives) = 1/(1+3) = 0.25
Recall = True Positives / (True Positives + False Negatives) = 1/(1+2) = 0.33

任何重叠 OK: 真阳性 = 2(Microsoft Corp.Steve 重叠 Steve Ballmer),假阳性 =2(CEOtoday),假负数 = 1 (Windows 7)

Precision = True Positives / (True Positives + False Positives) = 2/(2+2) = 0.55
Recall = True Positives / (True Positives + False Negatives) = 2/(2+1) = 0.66

然后让读者推断“实际性能”(当允许使用人工判断来决定哪些重叠差异显着,哪些不显着时,公正的人工检查器将给出的精度和召回率)介于两者之间两个。

报告 F1 度量通常也很有用,它是准确率和召回率的调和平均值,当您必须权衡准确率和召回率时,它可以提供一些“性能”概念。

【讨论】:

很好的答案。问题:在这种情况下,“真阴性”是什么意思?我相信它需要计算准确性。 假设我按照第二种策略进行评估(重叠是可以的)。如何处理像[史蒂夫] [鲍尔默]这样的情况?当两个(部分)匹配都正确时,如何计算真正的正数? @MatthewCornell,TN 是完全错过的预测,例如Windows 7,如果 NER 完美,这个名字应该在TP!但事实并非如此,你完全错过了它!此外,TP、FP、TN、FN 以不同的深思熟虑的方式组合在一起,例如准确度、精度、召回率、F1 分数,为您的 NER 算法/系统定义一个单一的价值评估指标。很多时候准确率是阴险的,所以人们使用准确率和召回率作为他们对准确率的评估指标,此外,F1-score 只不过是准确率和召回率的调和平均值,它旨在解决类别不平衡问题 @JanTrienes,我认为由于作者使用的 NER 模型足以捕捉名称及其各自实体之间的关系,因此有多种方法可以增加 TP,& 都是经验性的。而且,由于作者在这里没有提到型号,所以很难打电话。但是,最简单的想法是,由于这里的模型欠拟合,我们可以尝试使用更复杂的模型(增加数据无济于事,因为没有过度拟合的迹象!)。 对于准确率还是召回率在 NER 中更重要,您有什么看法? @KenBloom【参考方案2】:

在CoNLL-2003 NER task 中,评估基于正确标记的实体,而不是标记,如论文'Introduction to the CoNLL-2003 Shared Task: Language-Independent Named Entity Recognition' 中所述。如果系统在文档中识别出具有正确起点和终点的正确类型的实体,则该实体被正确标记。我更喜欢这种评估方法,因为它更接近实际任务的性能度量; NER 系统的用户关心实体,而不是单个令牌。

但是,您描述的问题仍然存在。如果您将 ORG 类型的实体标记为 LOC 类型,则会导致 LOC 误报和 ORG 误报。这个blog post有一个关于这个问题的有趣讨论。

【讨论】:

您的链接不再有效。这里是工作的。 CoNLL-2003 NER 任务:clips.uantwerpen.be/conll2003/ner 论文:clips.uantwerpen.be/conll2003/pdf/14247tjo.pdf【参考方案3】:

如前所述,衡量 NER 性能的方法有多种。可以分别评估实体在文本中的位置以及它们的类别(人、位置、组织等)的检测精度。或者将这两个方面结合在一个度量中。

您会在以下论文中找到一篇不错的评论:D. Nadeau, Semi-Supervised Named Entity Recognition: Learning to Recognize 100 Entity Types with Little Supervision (2007)。查看2.6 节。 NER的评估

【讨论】:

【参考方案4】:

这个问题没有简单的正确答案。有多种不同的方法来计算错误。 MUC比赛使用了一个,其他人使用了其他。

但是,为了帮助您解决眼前的困惑:

你有一组标签,不是吗?诸如 NONE、PERSON、ANIMAL、VEGETABLE 之类的东西?

如果令牌应该是人,而您将其标记为 NONE,那么这对于 NONE 来说是误报,对于 PERSON 来说是误报。如果一个令牌应该是 NONE 并且您将其标记为 PERSON,则相反。

所以你会得到每个实体类型的分数。

您还可以汇总这些分数。

【讨论】:

【参考方案5】:

为了清楚起见,这些是定义:

Precision = TP/(TP+FP) = 你发现的那部分是基本事实?

Recall = TP/(TP+FN) = 你恢复了哪一部分基本事实?

不一定总是相等,因为漏报的数量不一定等于误报的数量。

如果我正确理解您的问题,您将每个标记分配给两个以上可能的标签之一。为了使精确度和召回率有意义,您需要有一个binary classifier。因此,如果您将分类器表述为标记是否在“A”组中,则可以使用精度和召回率,然后对每个组重复。在这种情况下,错过的分类将被视为一个组的假阴性和另一组的假阳性两次。

如果您要进行这样的分类,它不是二进制的(将每个标记分配给一个组),那么查看标记对可能会很有用。将您的问题表述为“标记 X 和 Y 在同一个分类组中吗?”。这允许您计算所有节点对的精度和召回率。如果您的分类组被标记或具有相关含义,则这不合适。例如,如果您的分类组是“水果”和“蔬菜”,并且您将“苹果”和“橙子”都分类为“蔬菜”,那么即使分配了错误的组,该算法也会将其评分为真阳性。但是如果你的组没有标签,例如“A”和“B”,那么如果苹果和橙子都被归类为“A”,那么你可以说“A”对应于“Fruits”。

【讨论】:

【参考方案6】:

如果您正在训练一个 spacy ner 模型,那么他们的 scorer.py API 可以为您提供精确度、召回率和召回率。

代码和输出将采用以下格式:-

17

对于那些在以下链接中有相同问题的人:

spaCy/scorer.py '''蟒蛇

import spacy

from spacy.gold import GoldParse

from spacy.scorer import Scorer


def evaluate(ner_model, examples):

scorer = Scorer()
for input_, annot in examples:
    doc_gold_text = ner_model.make_doc(input_)
    gold = GoldParse(doc_gold_text, entities=annot)
    pred_value = ner_model(input_)
    scorer.score(pred_value, gold)
return scorer.scores

示例运行

examples = [
    ('Who is Shaka Khan?',
     [(7, 17, 'PERSON')]),
    ('I like London and Berlin.',
     [(7, 13, 'LOC'), (18, 24, 'LOC')])
]

ner_model = spacy.load(ner_model_path) # for spaCy's pretrained use 'en_core_web_sm'
results = evaluate(ner_model, examples)
'''
Output will be in format like:-
'uas': 0.0, 'las': 0.0, **'ents_p'**: 43.75, **'ents_r'**: 35.59322033898305, **'ents_f'**: 39.252336448598136, 'tags_acc': 0.0, 'token_acc': 100.0**strong text**

【讨论】:

以上是关于在命名实体识别中计算精度和召回率的主要内容,如果未能解决你的问题,请参考以下文章

计算超过 2 个类别的精度和召回率

如何计算聚类中的精度和召回率?

精度评定中的准确率(Precision)和召回率(Recall)

计算精度和召回率

如何在 Keras 中计算精度和召回率

如何计算精度和召回率