将自定义 NER 添加到 Spacy 3 管道

Add custom NER to Spacy 3 pipeline

我正在尝试基于 en_core_web_sm 管道构建自定义 Spacy 管道。据我所知,ner 已正确添加,因为它在打印时显示在管道名称中(见下文)。出于某种原因,当模型在文本上进行测试时,我没有得到任何结果,但是当自定义 ner 本身被使用时,正确的实体被提取和标记。我正在使用 Spacy 3.0.8 和 en_core_web_sm 管道 3.0.0.

import spacy


crypto_nlp = spacy.load('model-best')
nlp = spacy.load('en_core_web_sm')

nlp.add_pipe('ner', source=crypto_nlp, name="crypto_ner", before="ner")

print(nlp.pipe_names)

text = 'Ethereum'

doc = nlp(text)
for ent in doc.ents:
    print(ent.text, ent.label_)

输出:'['tok2vec'、'tagger'、'parser'、'crypto_ner'、'ner'、'attribute_ruler'、'lemmatizer' ]'

但是当我使用我的 ner 模型时:

doc = crypto_nlp(text)
for ent in doc.ents:
    print(ent.text, ent.label_)

输出:'Ethereum ETH'

从问题的细节中不清楚,但我的猜测是您的 crypto_nlp ner 依赖于一个单独的 tok2vec 组件,该组件在您采购时未包含在内。

由于不会共享此 tok2vec,最简单的方法是修改 ner 组件以包含 tok2vec 的独立副本,这称为“替换侦听器”: https://spacy.io/api/language#replace_listeners

如果 crypto_nlpnlp.pipe_names 作为 ['tok2vec', 'ner'],那么这应该在加载到第二个管道之前替换监听器,所以它现在是一个独立的组件:

crypto_nlp.replace_listeners("tok2vec", "ner", ["model.tok2vec"])
nlp.add_pipe('ner', source=crypto_nlp, name="crypto_ner", before="ner")