web-dev-qa-db-ja.com

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.8090.787 0.796 6178

取得元: http://www.davidsbatista.net/blog/2018/05/09/Named_Entity_Evaluation/

ありがとうございました!

10
ln pi

いい質問です。

まず、spaCyが参照しているBIOアノテーションスキームの代わりにBILUOアノテーションスキームを使用していることを明確にする必要があります。 spacyから documentation 文字は次のことを示します:

  • B:マルチトークンエンティティの最初のトークン。
  • I:マルチトークンエンティティの内部トークン。
  • L:マルチトークンエンティティの最後のトークン。
  • U:単一トークンエンティティ。
  • O:非エンティティトークン。

次に、いくつかの定義:

definitions

Spacyには、NERを評価するための組み込みクラスがあります。それはscorerと呼ばれます。スコアラーは、完全一致を使用して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パラメーターを指定してevaluate関数を呼び出し、各タグの結果を取得します。

それが役に立てば幸い :)

4
gdaras

@gdarasの答えは正しくありません。最初のコメントはその理由を示しています。のエンティティをフィルタリングする必要があります

pred_value = nlp(input_)

私はこのようにしました

pred_value.ents = [e for e in pred_value.ents if e.label_ == ent]
2
Andrey Zhukov

私はこれに取り組んできましたが、今ではこれによって統合されたwithing spacy プルリクエスト

ここで、Scorer().scoresを呼び出す必要があります。これにより、各エンティティの適合率、再現率、およびF1-スコアのメトリックを含む追加のキーents_per_typeを含む通常のdictが返されます。

それが役に立てば幸い!

1
ElBaulP