ValueError: nlp.add_pipe 现在采用已注册组件工厂的字符串名称,而不是可调用组件

问题描述

以下 link 显示了如何添加自定义实体规则,其中实体跨越多个令牌。执行此操作的代码如下:

import spacy
from spacy.pipeline import EntityRuler
nlp = spacy.load('en_core_web_sm',parse=True,tag=True,entity=True)

animal = ["cat","dog","artic fox"]
ruler = EntityRuler(nlp)
for a in animal:
    ruler.add_patterns([{"label": "animal","pattern": a}])
nlp.add_pipe(ruler)


doc = nlp("There is no cat in the house and no artic fox in the basement")

with doc.retokenize() as retokenizer:
    for ent in doc.ents:
        retokenizer.merge(doc[ent.start:ent.end])


from spacy.matcher import Matcher
matcher = Matcher(nlp.vocab)
pattern =[{'lower': 'no'},{'ENT_TYPE': {'REGEX': 'animal','OP': '+'}}]
matcher.add('negated animal',None,pattern)
matches = matcher(doc)


for match_id,start,end in matches:
    span = doc[start:end]
    print(span)

我试过了,但出现以下错误

  • 如果您使用 nlp.create_pipe('name') 创建组件:删除 nlp.create_pipe 并改为调用 nlp.add_pipe('name')

  • 如果你传入了一个TextCategorizer() 这样的组件:用字符串名称调用 nlp.add_pipe,例如nlp.add_pipe('textcat')

  • 如果您使用自定义组件:将装饰器 @Language.component(用于函数组件)或 @Language.factory(用于类组件/工厂)添加到您的自定义组件并为其分配名称,例如@Language.component('your_name')。然后您可以运行 nlp.add_pipe('your_name') 将其添加到管道中。

请问我该如何解决注意:spaCy 3.0.6 版

解决方法

您需要定义自己的方法来实例化实体标尺:

def get_ent_ruler(nlp,name):
    ruler = EntityRuler(nlp)
    for a in animal:
        ruler.add_patterns([{"label": "animal","pattern": a}])
    return ruler

然后,您可以通过以下方式使用它:

from spacy.language import Language
Language.factory("ent_ruler",func=get_ent_ruler)
nlp.add_pipe("ent_ruler",last=True)

另外,请注意您编写的模式无效。我认为你可以像这样修复它:

pattern =[{'lower': 'no'},{'ENT_TYPE': 'animal'}]

那么,结果是

no cat
no artic fox
,

对于 spaCy v2,添加实体标尺的正常方法如下所示:

ruler = EntityRuler(nlp)
nlp.add_pipe(ruler)
ruler.add_patterns(...)

对于 spaCy v3,您只想添加它的字符串名称并跳过单独实例化类:

ruler = nlp.add_pipe("entity_ruler")
ruler.add_patterns(...)

见:https://spacy.io/usage/v3#migrating-add-pipe