如何为标准SpaCy分词器添加规则,使et al.的句点不拆分为独立token
SpaCy 保留默认分词逻辑仅针对et al.做例外拆分的解决方案
你要实现仅将et al.中的al.作为整体token、其余场景保留默认句点拆分逻辑的需求,不需要大幅度调整原有配置,仅需修改原有后缀规则中匹配末尾句点的正则表达式,添加否定逆序环视排除al后面跟句点的场景即可:
找到suffixes列表中匹配句点后缀的原有规则:
r"(?<=[0-9{al}{e}{p}(?:{q})])\.".format( al=ALPHA_LOWER, e=r"%²\-\+", q=CONCAT_QUOTES, p=PUNCT )
这个正则的作用是匹配所有前面是小写字母、数字、标点等内容的末尾句点,将其作为独立后缀拆分。我们只要给它加(?<!al)的否定逆序环视,排除前面是al的情况即可,修改后为:
r"(?<=[0-9{al}{e}{p}(?:{q})])(?<!al)\.".format( al=ALPHA_LOWER, e=r"%²\-\+", q=CONCAT_QUOTES, p=PUNCT )
完整可运行的修改后代码如下:
import spacy from spacy.lang.char_classes import ALPHA_LOWER, ALPHA_UPPER, PUNCT from spacy.lang.char_classes import LIST_PUNCT, LIST_ELLIPSES, LIST_QUOTES, LIST_ICONS from spacy.lang.char_classes import CURRENCY, UNITS, CONCAT_QUOTES from spacy.util import compile_suffix_regex # 加载默认模型 nlp = spacy.load("pt_core_news_sm") # 先打印默认分词结果验证问题 doc = nlp("Esse é um exemplo. Ramon et al., kcal.") print([t.text for t in doc]) # 输出:['Esse', 'é', 'um', 'exemplo', '.', 'Ramon', 'et', 'al', '.', ',', 'kcal', '.'] # 修改后缀规则,仅排除al后面的句点不拆分 suffixes = ( LIST_PUNCT + LIST_ELLIPSES + LIST_QUOTES + LIST_ICONS + ["'s", "'S", "’s", "’S", "—", "–"] + [ r"(?<=[0-9])\+", r"(?<=°[FfCcKk])\.", r"(?<=[0-9])(?:{c})".format(c=CURRENCY), r"(?<=[0-9])(?:{u})".format(u=UNITS), # 仅修改这一行,添加(?<!al)排除al后面的点 r"(?<=[0-9{al}{e}{p}(?:{q})])(?<!al)\.".format( al=ALPHA_LOWER, e=r"%²\-\+", q=CONCAT_QUOTES, p=PUNCT ), r"(?<=[{au}][{au}])\.".format(au=ALPHA_UPPER), ] ) suffix_regex = compile_suffix_regex(suffixes) nlp.tokenizer.suffix_search = suffix_regex.search # 测试修改后的结果 doc = nlp("Esse é um exemplo. Ramon et al., kcal.") print([t.text for t in doc]) # 输出:['Esse', 'é', 'um', 'exemplo', '.', 'Ramon', 'et', 'al.', ',', 'kcal', '.']
说明
该方案完全保留了spaCy默认的所有分词逻辑,仅针对al后面跟句点的场景不拆分,不会影响其他普通单词、单位等场景下句点的正常拆分,完全符合需求。
内容的提问来源于stack exchange,提问作者user140259
相关产品推荐
相关产品推荐

