Spacy分词器无法一致识别句号为后缀,如何调整不破坏现有分词?
解决Spacy分词器对产品ID末尾句号拆分不一致的问题
你的问题核心是Spacy默认分词规则对不同格式的产品ID末尾句号处理不一致,原因是默认后缀规则未覆盖所有字母数字组合结尾的句号场景。要解决这个问题,只需在现有分词规则基础上添加自定义后缀规则,确保所有字母数字串后的句号都被识别为独立后缀,同时不影响已实现的连字符处理效果。
具体实现步骤
- 导入Spacy的后缀规则相关工具
- 扩展默认后缀规则,添加匹配字母数字组合后句号的正则
- 编译新的后缀正则并替换原分词器的后缀规则
完整整合代码
import spacy from spacy.lang.char_classes import ALPHA, ALPHA_LOWER, ALPHA_UPPER, NUMERIC from spacy.lang.char_classes import CONCAT_QUOTES, LIST_ELLIPSES, LIST_ICONS from spacy.util import compile_infix_regex, compile_suffix_regex # 加载默认模型 nlp = spacy.load("en_core_web_sm") # ---------------------- 保留原有连字符处理的中缀规则 ---------------------- infixes = ( LIST_ELLIPSES + LIST_ICONS + [ r"(?<=[0-9])[+\-\*^](?=[0-9-])", r"(?<=[{al}{q}])\.(?=[{au}{q}])".format( al=ALPHA_LOWER, au=ALPHA_UPPER, q=CONCAT_QUOTES ), r"(?<=[{a}]),(?=[{a}])".format(a=ALPHA), # 已注释拆分字母间连字符的规则,确保带连字符的产品ID不被拆分 # r"(?<=[{a}])(?:{h})(?=[{a}])".format(a=ALPHA, h=HYPHENS), r"(?<=[{a}0-9])[:<>=/](?=[{a}])".format(a=ALPHA), ] ) infix_re = compile_infix_regex(infixes) nlp.tokenizer.infix_finditer = infix_re.finditer # ---------------------- 添加自定义后缀规则处理末尾句号 ---------------------- # 获取默认后缀规则列表 suffixes = nlp.Defaults.suffixes # 添加新规则:匹配字母/数字组合后的末尾句号,强制拆分 # 正则含义:前置字符为至少一个字母或数字,句号位于字符串结尾 custom_suffix = r"(?<=[{al}{num}])\.$".format(al=ALPHA, num=NUMERIC) suffixes.insert(0, custom_suffix) # 插入到列表开头,确保优先匹配 # 编译新的后缀正则并替换分词器规则 suffix_re = compile_suffix_regex(suffixes) nlp.tokenizer.suffix_search = suffix_re.search # ---------------------- 验证效果 ---------------------- # 测试句号拆分一致性 test_texts = ["I want to buy the new ASX8E11F.", "I want to buy the new RK8BX."] for text in test_texts: doc = nlp(text) print(f"文本: {text}") print("分词结果:", [(t.text, t.tag_) for t in doc]) print("分词解释:", nlp.tokenizer.explain(text)) print("---") # 验证连字符产品ID的处理不受影响 doc = nlp("AXDR-PXXT-001") print("连字符产品ID测试:", [t.text for t in doc])
预期输出
文本: I want to buy the new ASX8E11F. 分词结果: [('I', 'PRON'), ('want', 'VERB'), ('to', 'PART'), ('buy', 'VERB'), ('the', 'DET'), ('new', 'ADJ'), ('ASX8E11F', 'NOUN'), ('.', 'PUNCT')] 分词解释: [('TOKEN', 'I'), ('TOKEN', 'want'), ('TOKEN', 'to'), ('TOKEN', 'buy'), ('TOKEN', 'the'), ('TOKEN', 'new'), ('TOKEN', 'ASX8E11F'), ('SUFFIX', '.')] --- 文本: I want to buy the new RK8BX. 分词结果: [('I', 'PRON'), ('want', 'VERB'), ('to', 'PART'), ('buy', 'VERB'), ('the', 'DET'), ('new', 'ADJ'), ('RK8BX', 'NOUN'), ('.', 'PUNCT')] 分词解释: [('TOKEN', 'I'), ('TOKEN', 'want'), ('TOKEN', 'to'), ('TOKEN', 'buy'), ('TOKEN', 'the'), ('TOKEN', 'new'), ('TOKEN', 'RK8BX'), ('SUFFIX', '.')] --- 连字符产品ID测试: ['AXDR-PXXT-001']
关键说明
- 自定义后缀规则
(?<=[{al}{num}])\.$确保只要句号前是字母/数字组合且位于字符串末尾,就会被拆分为独立后缀。 - 将新规则插入到后缀列表开头,保证优先于默认规则匹配,避免被其他规则覆盖。
- 原有连字符的中缀规则完全保留,不会影响带连字符的产品ID分词效果。
内容的提问来源于stack exchange,提问作者scarpacci
相关产品推荐
相关产品推荐

