如何配置spaCy en_core_web_sm分词器规则实现正确分词?
问题分析与解决方案
问题根源
你遇到的分词错误主要来自三个点:
- 未处理
M=/H=这类前缀结构:默认分词规则无法识别大写字母+=的组合,导致M=20kg被当成一个整体token,没有先拆分出M=。 - 中缀规则不匹配
kg/H=场景:默认的/中缀规则无法在无空格的情况下,正确拆分kg和H=之间的/,要么把/拆成单独token但后续H=200未拆分,要么把/H=当成一个整体。 - 后缀规则顺序错误:你把单位后缀规则
append到列表末尾,导致它被其他默认后缀规则优先匹配,无法触发数字与单位的拆分。
实现正确分词的代码调整
需要同时修改前缀、后缀、中缀三类分词规则,确保每个部分都能按预期触发:
import spacy from spacy.lang.char_classes import UNITS from spacy.util import compile_infix_regex, compile_prefix_regex, compile_suffix_regex # 加载模型 nlp = spacy.load('en_core_web_sm') s = "This string M=20kg/H=200mm" # 1. 添加前缀规则:拆分M=、H=这类大写字母+等号的结构 prefixes = list(nlp.Defaults.prefixes) prefixes.append(r"[A-Z]+=") nlp.tokenizer.prefix_search = compile_prefix_regex(prefixes).search # 2. 调整后缀规则:优先匹配数字后的单位(如kg、mm) suffixes = list(nlp.Defaults.suffixes) # 将单位后缀规则插入到列表最前面,确保优先匹配 unit_suffix_regex = rf"(?<=\d)({UNITS})" suffixes.insert(0, unit_suffix_regex) # 移除默认规则中重复的单位匹配,避免冲突 suffixes = [rule for rule in suffixes if not rule.endswith(UNITS)] nlp.tokenizer.suffix_search = compile_suffix_regex(suffixes).search # 3. 调整中缀规则:确保/在字母单位和字母=之间被单独拆分 infixes = list(nlp.Defaults.infixes) infixes.append(r"(?<=[a-zA-Z])\/(?=[A-Z]+=)") nlp.tokenizer.infix_finditer = compile_infix_regex(infixes).finditer # 测试分词 doc = nlp(s) print([token.text for token in doc]) # 输出:['This', 'string', 'M=', '20', 'kg', '/', 'H=', '200', 'mm']
规则调整说明
- 前缀规则:通过
[A-Z]+=匹配所有大写字母加等号的组合,让分词器优先拆分出M=、H=这类标识,避免它们和后续数字、单位绑定。 - 后缀规则:把数字+单位的匹配规则放在最前面,确保
20kg能被拆成20和kg,同时移除默认规则中重复的单位匹配,防止规则冲突。 - 中缀规则:新增
(?<=[a-zA-Z])\/(?=[A-Z]+=)规则,专门匹配字母结尾(如kg)和大写字母+等号(如H=)之间的/,确保它被拆成单独token。
内容的提问来源于stack exchange,提问作者Nadir Bašić
相关产品推荐
相关产品推荐

