使用Spacy EntityRuler添加PHONE_NUMBER实体失效问题求助
Spacy EntityRuler添加PHONE_NUMBER实体失效问题求助
嘿,我瞅见你在Spacy里用EntityRuler定义PHONE_NUMBER实体的时候碰钉子了——你说这个匹配模式用Matcher能正常工作,但做成实体规则就没效果,运行代码后电话号码还被拆成了两个CARDINAL实体,这就帮你捋捋问题出在哪~
先还原下你的问题场景,你的代码是这样的:
import spacy from spacy.pipeline import EntityRuler nlp = spacy.load("en_core_web_sm") patterns = [ { "label": "PHONE_NUMBER", "pattern": [ {"ORTH": "("}, {"SHAPE": "ddd"}, {"ORTH": ")"}, {"IS_SPACE": True, "OP": "?"}, {"SHAPE": "ddd"}, {"ORTH": "-"}, {"SHAPE": "dddd"}, ], } ] entity_ruler = EntityRuler(nlp, patterns=patterns, overwrite_ents=True) nlp.add_pipe("entity_ruler", before="ner") doc = nlp("You can reach me at (111) 111-1111.") for ent in doc.ents: print(ent.text, ent.label_)
当前输出是:
111 CARDINAL 111 CARDINAL
问题根源
你这里犯了一个小疏忽:你先初始化了带有自定义pattern的entity_ruler实例,但后面调用nlp.add_pipe("entity_ruler")的时候,相当于重新创建了一个空的EntityRuler,根本没把你定义的pattern加进去!自然就匹配不到电话号码,只能让原生的NER把数字识别成CARDINAL了。
修正方案
有两种正确的做法,选哪种都可以:
方案一:把初始化好的实体Ruler实例添加到管道
import spacy from spacy.pipeline import EntityRuler nlp = spacy.load("en_core_web_sm") patterns = [ { "label": "PHONE_NUMBER", "pattern": [ {"ORTH": "("}, {"SHAPE": "ddd"}, {"ORTH": ")"}, {"IS_SPACE": True, "OP": "?"}, {"SHAPE": "ddd"}, {"ORTH": "-"}, {"SHAPE": "dddd"}, ], } ] # 初始化带pattern的实体Ruler entity_ruler = EntityRuler(nlp, patterns=patterns, overwrite_ents=True) # 把这个实例添加到管道,放在NER之前 nlp.add_pipe(entity_ruler, before="ner") doc = nlp("You can reach me at (111) 111-1111.") for ent in doc.ents: print(ent.text, ent.label_)
方案二:直接通过add_pipe传入配置参数
import spacy nlp = spacy.load("en_core_web_sm") patterns = [ { "label": "PHONE_NUMBER", "pattern": [ {"ORTH": "("}, {"SHAPE": "ddd"}, {"ORTH": ")"}, {"IS_SPACE": True, "OP": "?"}, {"SHAPE": "ddd"}, {"ORTH": "-"}, {"SHAPE": "dddd"}, ], } ] # 直接在add_pipe时指定pattern和overwrite_ents参数 nlp.add_pipe("entity_ruler", before="ner", config={"patterns": patterns, "overwrite_ents": True}) doc = nlp("You can reach me at (111) 111-1111.") for ent in doc.ents: print(ent.text, ent.label_)
效果验证
修正后运行代码,就能得到正确的输出了:
(111) 111-1111 PHONE_NUMBER
这里的overwrite_ents=True也很关键,它会让EntityRuler识别的实体覆盖原生NER的结果,确保电话号码不会被拆分成其他实体类型~
备注:内容来源于stack exchange,提问作者user1255603
相关产品推荐
相关产品推荐

