基于规则的Tokenization:正则表达式、字典匹配、最大匹配法
Tokenization 的第一步,往往不是上模型,而是先拿规则顶上。说白了,规则就是人工写死的模式。你告诉程序:“看到这个就切一刀”。
我最早做 NLU 项目的时候,就是靠正则和字典撑起来的。数据量不大,规则够用,跑得又快。今天我们就聊聊这三板斧:正则表达式、字典匹配、最大匹配法。
正则表达式直接分词
用正则做 tokenization,最简单,也最容易翻车。我的习惯是——先确定你的 长什么样。
比如英文,基本就是 \w+ 或者更细致的 [A-Za-z]+。中文呢?单字、双字、人名、地名,正则覆盖面有限。
import re
text = "I love Python, and it's great!"
tokens = re.findall(r"\w+", text)
print(tokens)
# ['I', 'love', 'Python', 'and', 'it', 's', 'great']
注意到 it's 被拆成了 it 和 s。这就是正则的局限——它不懂语法,只认模式。
你想想看,如果要处理「don't」「can't」这类缩写,正则就得写 \w+(?:'\w+)?。规则越堆越多,维护成本就上去了。
我的建议是:正则适合做粗切或预处理。比如去掉标点、过滤数字。别指望它搞定一切。
字典匹配:查表分词
字典匹配比正则聪明一点。你把所有可能的词装进一个集合(set),然后扫描文本,看哪个连续片段在字典里。
但这里有个工程问题——怎么确定长度?你从头扫,每次取多长去查?这就是最大匹配法要解决的。
- 正向最大匹配:从左向右,先取最长可能词,匹配不到就缩短。
- 逆向最大匹配:从右向左,同理。
- 双向最大匹配:两个方向都跑,选结果更优的那个。
我记得有一次做中文地址解析,用正向最大匹配总把「北京市朝阳区」切成「北京/市朝/阳区」。换了逆向匹配才正确分出「北京市/朝阳区」。所以双向匹配并不是摆设。
class DictTokenizer:
def __init__(self, words, max_len=5):
self.dict = set(words)
self.max_len = max_len
def forward_max_match(self, text):
tokens = []
i = 0
while i < len(text):
matched = text[i]
for j in range(min(self.max_len, len(text) - i), 0, -1):
word = text[i:i+j]
if word in self.dict:
matched = word
break
tokens.append(matched)
i += len(matched)
return tokens
最大匹配法的核心假设是:字典覆盖了所有合理词。但新词、未登录词会直接拆成单字。我曾经被一个产品名「阿帕奇」坑过,字典里只有「阿帕」「奇」,结果分词全乱。
三种方法对比
下面这个表格,帮你一眼看清差异:
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 正则表达式 | 简单、快、无外挂 | 规则难维护、对新词不友好 | 预清洗、简单英文 |
| 字典匹配(正向/逆向) | 基建要求低、可控 | 对字典质量极度依赖、长度偏好 | 封闭领域的专业分词 |
| 双向最大匹配 | 精度相对高、消歧能力强 | 速度翻倍、实现稍复杂 | 通用场景、快速基线 |
说白了,规则型词法分析器的天花板就是你的字典。你投入多少人力维护字典,它就回报多少准确率。
基于规则的分词流程
下面这张图,是我自己做项目时常用的决策流程。先试正则过滤噪声,再用字典匹配做核心切分,最后用后处理修正明显错误。
经验之谈:我在线上部署过一个 OCR 后处理管线,纯规则分词,字典只有 2 万条,速度跑到了 1ms/句。但一旦遇到未登录词就崩。后来我加了个“最小单字长度”的后处理——连续单字超过 3 个就触发特殊规则。嗯,勉强能用。
实战中的小心思
- 字典加载:用
set或frozenset,普通list会导致in操作变成 O(n)。 - 最大长度设置:通常取字典中最长词的长度,或者硬编码 5~10。太长会引入大量无意义匹配。
- 中文编码:如果你处理中文,Python 3 的 str 是 Unicode,可以直接索引字符,但要注意中文字符宽度不等于1个字节。
- 性能优化:字典匹配可用前缀树(Trie)来加速,但如果你字典不大(<10万),set+遍历也够。
我个人习惯是:先用正则把 URL、邮箱、数字这些“强模式”提走,剩下部分交给字典匹配。这样字典匹配的压力小很多,准确率也稳。
基于规则的 Tokenization 虽然古老,但在工业界的冷启动阶段、或者领域极度垂直的场景下,依然是最可靠的方案。记住一句:规则定了,天花板就定了。想突破,就得往统计和模型走。但那是后面的话题了——我们先把规则玩透。