Nlp 仅来自短语匹配器的Spacy实体

Nlp 仅来自短语匹配器的Spacy实体,nlp,spacy,Nlp,Spacy,我正在使用一个NLP项目。我有一个要标记为新实体类型的短语列表。我最初尝试训练一个NER模型,但由于有一个有限的术语列表,我认为简单地使用匹配器应该更容易。我在中看到,您可以基于匹配器将实体添加到文档中。我的问题是:如何为新的实体执行此操作,而不让NER管道将任何其他标记标记为该实体?理想情况下,只有通过matcher找到的标记才应标记为实体,但我需要将其作为标签添加到NER模型中,然后将一些标记为实体 关于如何最好地实现这一点,有什么建议吗?谢谢 我认为您可能希望实现类似的功能,即使用短语匹配

我正在使用一个NLP项目。我有一个要标记为新实体类型的短语列表。我最初尝试训练一个NER模型,但由于有一个有限的术语列表,我认为简单地使用匹配器应该更容易。我在中看到,您可以基于匹配器将实体添加到文档中。我的问题是:如何为新的实体执行此操作,而不让NER管道将任何其他标记标记为该实体?理想情况下,只有通过matcher找到的标记才应标记为实体,但我需要将其作为标签添加到NER模型中,然后将一些标记为实体


关于如何最好地实现这一点,有什么建议吗?谢谢

我认为您可能希望实现类似的功能,即使用
短语匹配器
并分配实体。spaCy的内置实体识别器也只是一个管道组件,因此您可以将其从管道中删除并添加自定义组件:

nlp = spacy.load('en')               # load some model
nlp.remove_pipe('ner')               # remove the entity recognizer
entity_matcher = EntityMatcher(nlp)  # use your own entity matcher component
nlp.add_pipe(entity_matcher)         # add it to the pipeline
您的实体匹配器组件可以如下所示:

from spacy.matcher import PhraseMatcher
from spacy.tokens import Span

class EntityMatcher(object):
    name = 'entity_matcher'

    def __init__(self, nlp, terms, label):
        patterns = [nlp(term) for term in terms]
        self.matcher = PhraseMatcher(nlp.vocab)
        self.matcher.add(label, None, *patterns)

    def __call__(self, doc):
        matches = self.matcher(doc)
        spans = []
        for label, start, end in matches:
            span = Span(doc, start, end, label=label)
            spans.append(span)
        doc.ents = spans
        return doc
初始化组件时,它会为术语创建匹配模式,并将它们添加到短语匹配器中。我的示例假设您有一个
术语列表
和一个
标签
,您要为这些术语分配:

entity_matcher = EntityMatcher(nlp, your_list_of_terms, 'SOME_LABEL')
nlp.add_pipe(entity_matcher)

print(nlp.pipe_names)  # see all components in the pipeline
在对文本字符串调用
nlp
时,spaCy将标记文本文本以创建
Doc
对象,并按顺序调用
Doc
上的各个管道组件。然后,自定义组件的
\uuuu call\uuuu
方法在文档中查找匹配项,为每个匹配项创建
Span
(这允许您分配自定义标签),最后将它们添加到
doc.ents
属性并返回
doc


您可以根据自己的喜好构造管道组件–例如,您可以将其扩展为从文件加载到术语列表中,或使其向
PhraseMatcher

添加不同标签的多个规则。从spacy v2.1开始,spacy提供了一个开箱即用的解决方案:类

要仅匹配您关心的实体,您可以在添加自定义组件之前禁用实体管道组件,或者实例化空语言模型并将自定义组件添加到该模型中,例如

from spacy.lang.en import English
from spacy.pipeline import EntityRuler

nlp = English()

my_patterns = [{"label": "ORG", "pattern": "spacy team"}]
ruler = EntityRuler(nlp)
ruler.add_patterns(my_patterns)
nlp.add_pipe(ruler)

doc = nlp("The spacy team are amazing!")
assert str(doc.ents[0]) == 'spacy team'

如果您只想将文档标记化,并从术语列表中精确匹配实体,那么实例化空语言模型可能是最简单的解决方案。

谢谢您的回答,一如既往!我发现这个github示例也特别有用: