EntityRuler
(实体规则)组件,让你可以基于模式字典添加命名实体,从而可以轻松地将基于规则的命名实体识别和统计命名实体识别结合起来,以使管道更加强大。
实体模式
实体模式的字典具有两个键:其中"label"
指定了实体匹配成功后分配的标签;
"pattern"
指定匹配模式。实体规则接受两种类型的模式:
- 短语模式用于精确字符串匹配
{"label": "ORG", "pattern": "Apple"}
- Token模式
{"label": "GPE", "pattern": [{"LOWER": "san"}, {"LOWER": "francisco"}]}
使用实体规则
EntityRuler
是一个管道组件,通常通过nlp.add_pipe
方法添加。当你在一个文本对象上调用nlp
对象时,它将找到doc
中的匹配项,使用指定的模式标签作为实体标签,并将他们作为实体添加到doc.ents
中。如果有匹配重叠,那么模式匹配将优先匹配尽量多的token。如果他们恰巧又长度相同,则选在在Doc
中最早出现的匹配作为结果。
# spacy v3.0 python 3
from spacy.lang.en import English
nlp = English()
ruler = nlp.add_pipe("entity_ruler")
patterns = [{"label": "ORG", "pattern": "Apple"},
{"label": "GPE", "pattern": [{"LOWER": "san"}, {"LOWER": "francisco"}]}]
ruler.add_patterns(patterns)
doc = nlp("Apple is opening its first big office in San Francisco.")
print([(ent.text, ent.label_) for ent in doc.ents])
实体规则旨在通过与现用的管道组件集成然后增强命名实体识别器。如果在ner
组件之前添加,则实体识别器将基于现有的实体跨度并围绕它调整预测。某种情况下,这可以显著的提升预测准确性。如果在ner
组件之后添加,如果他们在现有模型预测的实体没有重叠,则实体规则只会在doc.ents
添加实体跨度。你可以在初始化时设置verwrite_ents=True
来覆盖重叠实体。
# spacy v3.0 python 3
import spacy
nlp = spacy.load("en_core_web_sm")
ruler = nlp.add_pipe("entity_ruler")
patterns = [{"label": "ORG", "pattern": "MyCorp Inc."}]
ruler.add_patterns(patterns)
doc = nlp("MyCorp Inc. is a company in the U.S.")
print([(ent.text, ent.label_) for ent in doc.ents])
验证和调试EntityRuler
模式
实体规则通过设置"validate"
来验证模型,具体参见验证和调试模式
ruler = nlp.add_pipe("entity_ruler", config={"validate": True})
给模式添加 ID
EntityRuler
可以为每个模式添加id
属性。使用id
属性后就允许将多个模式关联到同一实体。
# spacy v3.0 python 3
from spacy.lang.en import English
nlp = English()
ruler = nlp.add_pipe("entity_ruler")
patterns = [{"label": "ORG", "pattern": "Apple", "id": "apple"},
{"label": "GPE", "pattern": [{"LOWER": "san"}, {"LOWER": "francisco"}], "id": "san-francisco"},
{"label": "GPE", "pattern": [{"LOWER": "san"}, {"LOWER": "fran"}], "id": "san-francisco"}]
ruler.add_patterns(patterns)
doc1 = nlp("Apple is opening its first big office in San Francisco.")
print([(ent.text, ent.label_, ent.ent_id_) for ent in doc1.ents])
doc2 = nlp("Apple is opening its first big office in San Fran.")
print([(ent.text, ent.label_, ent.ent_id_) for ent in doc2.ents])
如果该id
属性包含在EntityRuler
模式中,ent_id_
属性将被设置为匹配到的实体所设置的id
。因此,在上面的示例中,很容易识别出“San Francisco”和“San Fran”都是同一个实体。
使用模式文件
你可用通过to_disk
和from_disk
方法把模式保存到JSONL文件并从JSONL文件中加载模式,其中文件中每行包含一个模式对象。PATTERNS.JSONL
文件格式如下:
{"label": "ORG", "pattern": "Apple"}
{"label": "GPE", "pattern": [{"LOWER": "san"}, {"LOWER": "francisco"}]}
保存、加载模式
ruler.to_disk("./patterns.jsonl")
new_ruler = nlp.add_pipe("entity_ruler").from_disk("./patterns.jsonl")
当您保存一个在管道中添加了EntityRuler
的nlp
对象时,其模式会自动导出到管道目录中(此时导出的是一个包含管道其他内容的文件夹,其中不知包含实体规则模式)。
nlp = spacy.load("en_core_web_sm")
ruler = nlp.add_pipe("entity_ruler")
ruler.add_patterns([{"label": "ORG", "pattern": "Apple"}])
nlp.to_disk("/path/to/pipeline")
保存的管道在其config.cfg
中包括"entity_ruler"
并且管道目录包含一个包含entityruler.jsonl
的模式文件。当您重新加载管道时,所有管道组件都将被恢复和反序列化-包括实体规则。这使你可以发布包含二进制权重和规则的管道包。
使用大量的短语模式
当使用大量短语模式(大约 > 10000)时,了解add_patterns
实体规则的是如何工作的就变的很重要。对于每个短语模式(phrase pattern),如果您尝试在现有管道的末尾添加EntityRuler
,那么EntityRuler
将调用nlp
对象来构造一个doc
对象。例如,一个POS
标记器并希望能够基于POS签名模式进行准确匹配。在这种情况下,您需要为实体规则设置"phrase_matcher_attr": "POS"
。
在大型列表中运行完整的语言管道时,大量短语模式可能需要更长的时间。从spaCy v2.2.4
开始,add_patterns
函数已被重构为在所有短语模式上使用nlp.pipe
,从而分别以5,000-100,000
个短语模式实现约10-20
倍的加速。但即使有了这种加速(但特别是如果您使用的是旧版本),add_patterns
功能仍可能需要很长时间。一个简单的解决办法是在添加短语模式时禁用其他语言管道。
ruler = nlp.add_pipe("entity_ruler")
patterns = [{"label": "TEST", "pattern": str(i)} for i in range(100000)]
with nlp.select_pipes(enable="tagger"):
ruler.add_patterns(patterns)
v1.5.2