如何从Spacy NER模型获得每个实体的预测概率?

问题描述 投票:0回答:3

我使用这个官方示例代码使用我自己的训练样本从头开始训练 NER 模型。

当我在新文本上使用此模型进行预测时,我想获得每个实体的预测概率。

    # test the saved model
    print("Loading from", output_dir)
    nlp2 = spacy.load(output_dir)
    for text, _ in TRAIN_DATA:
        doc = nlp2(text)
        print("Entities", [(ent.text, ent.label_) for ent in doc.ents])
        print("Tokens", [(t.text, t.ent_type_, t.ent_iob) for t in doc])

我无法在Spacy中找到一种方法来获得每个实体的预测概率。

我如何从 Spacy 获得这个概率?我需要它来对其应用截止。

python deep-learning nlp spacy named-entity-recognition
3个回答
5
投票

从 Spacy NER 模型获取每个实体的预测概率并非易事。 这是改编自here的解决方案:


import spacy
from collections import defaultdict

texts = ['John works at Microsoft.']

# Number of alternate analyses to consider. More is slower, and not necessarily better -- you need to experiment on your problem.
beam_width = 16
# This clips solutions at each step. We multiply the score of the top-ranked action by this value, and use the result as a threshold. This prevents the parser from exploring options that look very unlikely, saving a bit of efficiency. Accuracy may also improve, because we've trained on greedy objective.
beam_density = 0.0001 
nlp = spacy.load('en_core_web_md')


docs = list(nlp.pipe(texts, disable=['ner']))
beams = nlp.entity.beam_parse(docs, beam_width=beam_width, beam_density=beam_density)

for doc, beam in zip(docs, beams):
    entity_scores = defaultdict(float)
    for score, ents in nlp.entity.moves.get_beam_parses(beam):
        for start, end, label in ents:
            entity_scores[(start, end, label)] += score

l= []
for k, v in entity_scores.items():
    l.append({'start': k[0], 'end': k[1], 'label': k[2], 'prob' : v} )

for a in sorted(l, key= lambda x: x['start']):
    print(a)

### Output: ####

{'start': 0, 'end': 1, 'label': 'PERSON', 'prob': 0.4054479906820232}
{'start': 0, 'end': 1, 'label': 'ORG', 'prob': 0.01002015005487447}
{'start': 0, 'end': 1, 'label': 'PRODUCT', 'prob': 0.0008592912552754791}
{'start': 0, 'end': 1, 'label': 'WORK_OF_ART', 'prob': 0.0007666755792166002}
{'start': 0, 'end': 1, 'label': 'NORP', 'prob': 0.00034931990870877333}
{'start': 0, 'end': 1, 'label': 'TIME', 'prob': 0.0002786051849320804}
{'start': 3, 'end': 4, 'label': 'ORG', 'prob': 0.9990115861687987}
{'start': 3, 'end': 4, 'label': 'PRODUCT', 'prob': 0.0003378157477046507}
{'start': 3, 'end': 4, 'label': 'FAC', 'prob': 8.249734411749544e-05}


3
投票

抱歉,我没有更好的答案 - 我只能确认“梁”解决方案确实提供了一些“概率” - 尽管在我的情况下,我得到了太多 prob=1.0 的实体,即使在我只能摇头并归咎于训练数据太少。

我觉得很奇怪,Spacy 在没有任何信心的情况下报告了一个“实体”。我假设有一些阈值来决定 Spacy 何时报告实体以及何时不报告(也许我错过了)。就我而言,我看到置信度 0.6 报告为“这是一个实体”,而置信度 0.001 的实体则未报告。

在我的用例中,信心至关重要。对于给定的文本,Spacy(例如 Google ML)会报告“MY_ENTITY”的多个实例。我的代码必须决定哪些是“可信的”,哪些是误报的。我还没有看到上面代码返回的“概率”是否有任何实际价值。


0
投票

注意:beam_parse 无法通过上面的“nlp.entity.beam_parse()”访问,而是通过 v3 中的 .get_pipe() 函数调用:

导入spacy

将 pandas 导入为 pd

从集合导入defaultdict

nlp = spacy.load(r'C:\n_core_web_sm n_core_web_sm-3.7.1'上的路径)

确保指定存储 nlp 模型的路径!!!

df = pd.read_csv('yourdataset.csv')

确保指定数据集

df['Entities'] = [[] for _ in range(len(df))] # 初始化空列表

对于索引,df.iterrows() 中的行:

input_phrase = row['INPUT COLUMN']

try:

    input_phrase = str(input_phrase)

    response = nlp(input_phrase)

    beams = nlp.get_pipe("ner").beam_parse([response], beam_width=16, beam_density=0.0001)

    entity_scores = defaultdict(float)

    entries = []

    for beam in beams:

        for score, ents in nlp.get_pipe("ner").moves.get_beam_parses(beam):

            for start, end, label in ents:

                entity_scores[(start, end, label)] += score

    for key in entity_scores:

        start, end, label = key

        score = entity_scores[key]

        entry = f"Label: {label}, Text: {response[start:end]}, Score: {score:.4f};" # use ; as delimiter for unpacking

        entries.append(entry)

    print(entries)

    df.at[index, 'Entities'] = entries

    df.to_csv('spacy_scores_take99999.csv', index=False)

except:

    df.at[index, 'Entities'] = 'None'

df.to_csv('youroutputfile.csv',index=False)

这会将一个数组写入您的“实体”列,稍后可以使用 ; 解压缩该数组。作为分隔符。数组中的对象格式为:“标签:东西,文本:无论识别的对象是什么,得分:0.1234;”对于每个对象。

© www.soinside.com 2019 - 2024. All rights reserved.