添加具有空格的多个实体标尺(ValueError:'Entity_Ruler'管道中已存在)

Add multiple EntityRuler with spaCy (ValueError: #39;entity_ruler#39; already exists in pipeline)(添加具有空格的多个实体标尺(ValueError:#39;Entity_Ruler#39;管道中已存在))
本文介绍了添加具有空格的多个实体标尺(ValueError:'Entity_Ruler'管道中已存在)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下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])

我尝试添加另一个自定义实体标尺,如下所示:

flower = ["rose", "tulip", "african daisy"]
ruler = EntityRuler(nlp)
for f in flower:
    ruler.add_patterns([{"label": "flower", "pattern": f}])
nlp.add_pipe(ruler)

但我收到此错误:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-47-702f460a866f> in <module>()
      4 for f in flower:
      5     ruler.add_patterns([{"label": "flower", "pattern": f}])
----> 6 nlp.add_pipe(ruler)
      7 

~AppDataLocalContinuumanaconda3libsite-packagesspacylanguage.py in add_pipe(self, component, name, before, after, first, last)
    296                 name = repr(component)
    297         if name in self.pipe_names:
--> 298             raise ValueError(Errors.E007.format(name=name, opts=self.pipe_names))
    299         if sum([bool(before), bool(after), bool(first), bool(last)]) >= 2:
    300             raise ValueError(Errors.E006)

ValueError: [E007] 'entity_ruler' already exists in pipeline. Existing names: ['tagger', 'parser', 'ner', 'entity_ruler']

我的问题是:

  1. 如何添加另一个自定义实体标尺?

  2. 标签使用大写字母是否是最佳做法(例如,应该使用ruler.add_patterns([{"label": "ANIMAL", "pattern": a}])而不是ruler.add_patterns([{"label": "animal", "pattern": a}])

推荐答案

您可以通过更改名称将另一个自定义实体标尺添加到您的管道中(以避免名称冲突)。以下是要说明的一些代码,但请阅读下面的备注:

import spacy
from spacy.pipeline import EntityRuler
nlp = spacy.load('en_core_web_sm', disable = ['ner'])
rulerPlants = EntityRuler(nlp, overwrite_ents=True)
flowers = ["rose", "tulip", "african daisy"]
for f in flowers:
    rulerPlants.add_patterns([{"label": "flower", "pattern": f}])
animals = ["cat", "dog", "artic fox"]
rulerAnimals = EntityRuler(nlp, overwrite_ents=True)
for a in animals:
    rulerAnimals.add_patterns([{"label": "animal", "pattern": a}])

rulerPlants.name = 'rulerPlants'
rulerAnimals.name = 'rulerAnimals'
nlp.add_pipe(rulerPlants)
nlp.add_pipe(rulerAnimals)

doc = nlp("cat and artic fox, plant african daisy")
for ent in doc.ents:
    print(ent.text , '->', ent.label_)

#output:
#cat -> animal
#artic fox -> animal
#african daisy -> flower

我们可以验证管道是否包含两个实体标尺:

print(nlp.pipe_names)
# ['tagger', 'parser', 'rulerPlants', 'rulerAnimals']

备注:我建议使用更简单、更自然的方法制作一个新的实体标尺,其中包含两个实体标尺的规则:

rulerAll = EntityRuler(nlp)
rulerAll.add_patterns(rulerAnimals.patterns)
rulerAll.add_patterns(rulerPlants.patterns)
最后,关于您提出的有关实体标签的最佳实践的问题,通常使用大写字母的缩写(参见Spacy NER documentation) 例如ORG、LOC、Person等。

编辑以下问题:

1)如果您不需要Spacy的默认命名实体识别(NER),那么我建议禁用它,因为这将加速计算并避免干扰(请参阅关于此的讨论here)。禁用NER不会导致意外的下游结果(只是不会为默认实体LOC、ORG、Person等标记您的文档)。

2)编程中有这样一种想法:"简单复杂好。"(see here)。关于构成更简单的解决方案的内容可能存在一些主观性。我认为组件较少的处理流水线更简单(即包含两个实体标尺的流水线在我看来更复杂)。但是取决于您在配置、适应性等方面的需求。它可能更简单,因为您有几个不同的实体标尺,如本解决方案的第一部分所述。如果Spacy的作者能给出他们对这两种不同设计选择的看法,那就太好了。

3)自然可以直接创建上面的单实体标尺:

rulerAll = EntityRuler(nlp, overwrite_ents=True)
for f in flowers:
    rulerAll.add_patterns([{"label": "flower", "pattern": f}])
for a in animals:
    rulerAll.add_patterns([{"label": "animal", "pattern": a}])
上面为构造rulerAll而显示的其他代码旨在说明如何向实体标尺查询已添加到其中的模式列表。在实践中,我们会直接构造标尺,而不需要首先构造标尺植物和标尺动物。除非我们想要单独测试和分析它们(rulerPlants和rulerAnimal)。

这篇关于添加具有空格的多个实体标尺(ValueError:&#39;Entity_Ruler&#39;管道中已存在)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Leetcode 234: Palindrome LinkedList(Leetcode 234:回文链接列表)
How do I read an Excel file directly from Dropbox#39;s API using pandas.read_excel()?(如何使用PANDAS.READ_EXCEL()直接从Dropbox的API读取Excel文件?)
subprocess.Popen tries to write to nonexistent pipe(子进程。打开尝试写入不存在的管道)
I want to realize Popen-code from Windows to Linux:(我想实现从Windows到Linux的POpen-code:)
Reading stdout from a subprocess in real time(实时读取子进程中的标准输出)
How to call type safely on a random file in Python?(如何在Python中安全地调用随机文件上的类型?)