仅来自 PhraseMatcher 的 Spacy 实体
Spacy Entity from PhraseMatcher only
我正在使用 Spacy for a NLP project. I have a list of phrases I'd like to mark as a new entity type. I originally tried training a NER model but since there's a finite terminology list, I think simply using a Matcher should be easier. I see in the documentation,您可以将实体添加到基于匹配器的文档中。我的问题是:如何为 new 实体执行此操作,而不将 NER 管道标记为该实体的任何其他标记?理想情况下,只有通过我的匹配器找到的标记才应标记为实体,但我需要将其作为标签添加到 NER 模型中,然后最终将一些标记标记为实体。
关于如何最好地完成这项工作有什么建议吗?谢谢!
我认为您可能想要实现类似于 this example – i.e. a custom pipeline component 的东西,它使用 PhraseMatcher
并分配实体。 spaCy 的 built-in 实体识别器也只是一个管道组件——因此您可以将其从管道中删除并添加您的自定义组件:
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
当您的组件初始化时,它会为您的术语创建匹配模式,并将它们添加到短语匹配器中。我的示例假设您有一个 terms
列表和一个 label
列表,您想要为这些术语分配:
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
上的各个管道组件。然后,自定义组件的 __call__
方法会在文档中找到匹配项,为每个匹配项创建一个 Span
(允许您分配自定义标签),最后将它们添加到 doc.ents
属性 和 returns Doc
.
您可以根据自己的喜好构建您的管道组件——例如,您可以扩展它以从文件加载到您的术语列表中,或者让它为不同的标签添加多个规则到 PhraseMatcher
。
从 spacy v2.1 开始,spacy 提供了一个开箱即用的解决方案:EntityRuler class.
要仅匹配您关心的实体,您可以在添加自定义组件之前禁用实体管道组件,或者实例化一个空语言模型并向其中添加自定义组件,例如
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'
如果您只想对术语列表中的文档和完全匹配实体进行标记,那么实例化空语言模型可能是最简单的解决方案。
我正在使用 Spacy for a NLP project. I have a list of phrases I'd like to mark as a new entity type. I originally tried training a NER model but since there's a finite terminology list, I think simply using a Matcher should be easier. I see in the documentation,您可以将实体添加到基于匹配器的文档中。我的问题是:如何为 new 实体执行此操作,而不将 NER 管道标记为该实体的任何其他标记?理想情况下,只有通过我的匹配器找到的标记才应标记为实体,但我需要将其作为标签添加到 NER 模型中,然后最终将一些标记标记为实体。
关于如何最好地完成这项工作有什么建议吗?谢谢!
我认为您可能想要实现类似于 this example – i.e. a custom pipeline component 的东西,它使用 PhraseMatcher
并分配实体。 spaCy 的 built-in 实体识别器也只是一个管道组件——因此您可以将其从管道中删除并添加您的自定义组件:
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
当您的组件初始化时,它会为您的术语创建匹配模式,并将它们添加到短语匹配器中。我的示例假设您有一个 terms
列表和一个 label
列表,您想要为这些术语分配:
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
上的各个管道组件。然后,自定义组件的 __call__
方法会在文档中找到匹配项,为每个匹配项创建一个 Span
(允许您分配自定义标签),最后将它们添加到 doc.ents
属性 和 returns Doc
.
您可以根据自己的喜好构建您的管道组件——例如,您可以扩展它以从文件加载到您的术语列表中,或者让它为不同的标签添加多个规则到 PhraseMatcher
。
从 spacy v2.1 开始,spacy 提供了一个开箱即用的解决方案:EntityRuler class.
要仅匹配您关心的实体,您可以在添加自定义组件之前禁用实体管道组件,或者实例化一个空语言模型并向其中添加自定义组件,例如
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'
如果您只想对术语列表中的文档和完全匹配实体进行标记,那么实例化空语言模型可能是最简单的解决方案。