spaCy的NER是否可以通过一种方法来计算每种实体类型的指标?

时间:2018-10-17 13:26:19

标签: python entity metrics spacy ner

spaCy中的NER模型中是否有一种方法可以提取每种实体类型的指标(精度,召回率,f1得分)?

看起来像这样的东西

         precision    recall  f1-score   support

  B-LOC      0.810     0.784     0.797      1084
  I-LOC      0.690     0.637     0.662       325
 B-MISC      0.731     0.569     0.640       339
 I-MISC      0.699     0.589     0.639       557
  B-ORG      0.807     0.832     0.820      1400
  I-ORG      0.852     0.786     0.818      1104
  B-PER      0.850     0.884     0.867       735
  I-PER      0.893     0.943     0.917       634

平均/总计0.809 0.787 0.796 6178

摘自:http://www.davidsbatista.net/blog/2018/05/09/Named_Entity_Evaluation/

谢谢!

4 个答案:

答案 0 :(得分:4)

很好的问题。

首先,我们应该澄清一下,spaCy使用BILUO注释方案,而不是您所指的BIO注释方案。 在documentation中,字母表示以下内容:

  • B:多令牌实体的第一个令牌。
  • I:多令牌实体的内部令牌。
  • L:多令牌实体的最终令牌。
  • U:单令牌实体。
  • O:非实体令牌。

然后,一些定义:

definitions

Spacy具有一个内置类来评估NER。它称为得分手。 记分员使用精确匹配来评估NER。精度分数返回为ents_p,召回率返回为ents_r,F1分数返回为ents_f。

唯一的问题是它返回文档中所有标签的分数。但是,我们只能使用所需的TAG调用函数,并获得所需的结果。

所有代码都应该像这样:

import spacy
from spacy.gold import GoldParse
from spacy.scorer import Scorer

def evaluate(nlp, examples, ent='PERSON'):
    scorer = Scorer()
    for input_, annot in examples:
        text_entities = []
        for entity in annot.get('entities'):
            if ent in entity:
                text_entities.append(entity)
        doc_gold_text = nlp.make_doc(input_)
        gold = GoldParse(doc_gold_text, entities=text_entities)
        pred_value = nlp(input_)
        scorer.score(pred_value, gold)
    return scorer.scores


examples = [
    ("Trump says he's answered Mueller's Russia inquiry questions \u2013 live",{"entities":[[0,5,"PERSON"],[25,32,"PERSON"],[35,41,"GPE"]]}),
    ("Alexander Zverev reaches ATP Finals semis then reminds Lendl who is boss",{"entities":[[0,16,"PERSON"],[55,60,"PERSON"]]}),
    ("Britain's worst landlord to take nine years to pay off string of fines",{"entities":[[0,7,"GPE"]]}),
    ("Tom Watson: people's vote more likely given weakness of May's position",{"entities":[[0,10,"PERSON"],[56,59,"PERSON"]]}),
]

nlp = spacy.load('en_core_web_sm')
results = evaluate(nlp, examples)
print(results)

使用适当的ent参数调用评估函数以获取每个标签的结果。

希望它会有所帮助:)

答案 1 :(得分:0)

@gdaras的答案不正确。第一条评论给出了为什么的想法。 您应该过滤

的实体
pred_value = nlp(input_)

我是这样做的

pred_value.ents = [ent for ent in pred_value.ents if ent.label_ == ent]

答案 2 :(得分:0)

我一直在研究这个问题,现在Pull Request对此进行了整合。

现在,您只需要调用Scorer().scores,它将返回带有附加键ents_per_type的普通字典,其中将包含每个实体的指标Precision,Recall和F1-Score。

希望有帮助!

答案 3 :(得分:0)

来自 spacy v3,

import spacy
nlp = spacy.load("your_model_path")
examples = []
data = [("Taj mahal is in Agra.", {"entities": [(0, 9, 'name'),
(16, 20, 'place')})]
for text, annots in data:
    examples.append(Example.from_dict(ner_model.make_doc(text), annots))
print(nlp.evaluate(examples)) # This will provide overall and per entity metrics