如何在spaCy的norm_exceptions.py中添加自定义俚语及函数调用时机
关于spaCy中
add_lookups调用时机的正确姿势 好问题!这个时机的选择直接决定了你的自定义俚语规范化规则能不能生效——答案是必须在加载nlp模型之后,调用nlp处理任何文本之前执行add_lookups调用。
为什么是这个时机?
spaCy的lex_attr_getters是语言默认属性的 getter 集合,其中NORM属性负责计算token的规范化形式(比如把俚语转换成标准表达)。当你加载预训练模型后,nlp对象已经初始化了一套默认的规范化规则,但还没开始处理任何文本。这时候修改lex_attr_getters[NORM],后续所有通过这个nlp对象处理的token都会自动应用你更新后的规则。
如果把add_lookups放在doc = nlp(...)之后,那之前生成的doc已经用了默认规则,修改不会对它生效;而且除非你重新处理文本,否则新规则也没法发挥作用——这显然不是我们想要的效果。
正确的代码示例
import spacy from spacy.lang.en import NORM from spacy.util import add_lookups # 先定义你的俚语-标准表达映射,以及可能的基础规则 NORM_EXCEPTIONS = {"frfr": "for real for real", "cap": "lie", "vibe": "atmosphere"} BASE_NORMS = {} # 如果你有额外的基础规范化规则可以放在这里 # 1. 第一步:加载预训练模型 nlp = spacy.load('en') # 2. 第二步:在这里调用add_lookups,更新NORM属性的getter nlp.Defaults.lex_attr_getters[NORM] = add_lookups( nlp.Defaults.lex_attr_getters[NORM], # 继承原有的默认规则 NORM_EXCEPTIONS, # 添加上你的俚语映射 BASE_NORMS # 可选:添加额外基础规则 ) # 3. 第三步:之后再处理文本,此时俚语会被正确规范化 doc = nlp(u'frfr that cap has a weird vibe') for token in doc: print(f"原文本: {token.text}, 规范化后: {token.norm_}")
额外提示
- 这种修改是全局生效的:只要你用这个nlp对象处理文本,所有token都会应用新的规范化规则,所以不需要每次处理前都重复调用
add_lookups。 - 如果需要多次复用这个自定义的nlp对象,可以把初始化逻辑封装成一个函数,比如:
这样每次调用def get_custom_nlp(): nlp = spacy.load('en') nlp.Defaults.lex_attr_getters[NORM] = add_lookups(...) return nlpget_custom_nlp()都能得到带有自定义规则的nlp实例。
内容的提问来源于stack exchange,提问作者Lee He




