2、分词基础技术:正向最大匹配法(FMM)、逆向最大匹配法(BMM)、双向最大匹配法
聊到中文分词,我第一个想跟你聊的,就是这三种最经典的匹配方法。它们虽然看起来简单,但却是很多工业级分词系统的基石。说白了,没有它们打底,后面那些高大上的统计模型、深度学习模型,效果都会大打折扣。
我记得刚入行那会儿,带我的老工程师就跟我说:「别小看最大匹配法,它虽然笨,但稳。」后来我在做搜索日志分析时,确实体会到了这一点。好,咱们一个一个来看。
2.1 正向最大匹配法(FMM)
FMM 的思路非常直白:从左往右扫描句子,每次取尽可能长的词。
具体怎么做呢?
- 先准备一个词典,里面装着所有可能的词。
- 设定一个「最大词长」,比如 5 个字符。
- 从句子开头取 5 个字符,去词典里查。
- 查到了,就切出来,指针往后移 5 位。
- 没查到,就缩短一个字符,变成 4 个字符再查。
- 重复,直到切完整个句子。
我举个例子你就明白了。句子是:「我们在野生动物园玩」。
假设最大词长是 5:
- 取「我们在野生」→ 没查到,缩短
- 取「我们在野」→ 没查到,缩短
- 取「我们在」→ 查到!切出来
- 剩下「野生动物园玩」→ 取「野生动物园」→ 查到!切出来
- 剩下「玩」→ 查到!切出来
结果就是:「我们 / 在 / 野生动物园 / 玩」
嗯,这里要注意:如果词典里没有「野生动物园」,只有「野生」和「动物」,那结果就会变成「我们 / 在 / 野生 / 动物园 / 玩」。你看,词典的质量直接决定了分词效果。
核心要点: FMM 是贪心算法,每次取最长匹配。优点是速度快,缺点是容易产生歧义。
2.2 逆向最大匹配法(BMM)
BMM 和 FMM 几乎一模一样,唯一的区别是:从右往左扫描。
为什么要这么做?
我在项目中遇到过这样一个坑:用 FMM 切「研究生命科学」,结果变成了「研究生 / 命 / 科学」。这明显不对,原意是「研究 / 生命 / 科学」。
但换成 BMM 呢?从右往左切:
- 取「命科学」→ 没查到,缩短
- 取「科学」→ 查到!切出来
- 剩下「研究生」→ 查到!切出来
- 剩下「研究」→ 查到!切出来
结果就是「研究 / 生命 / 科学」。完美!
为什么会这样?因为中文里很多歧义结构,比如「AB/C」和「A/BC」这种,BMM 往往能更好地处理「偏正结构」的歧义。我个人的经验是,BMM 在大多数场景下准确率比 FMM 高那么一两个百分点。
小技巧: 如果你只能选一种方法做快速分词,我建议优先选 BMM。它处理「动宾结构」和「偏正结构」的歧义时,表现通常更好。
2.3 双向最大匹配法
既然 FMM 和 BMM 各有优劣,那把它们结合起来呢?这就是双向最大匹配法。
做法很简单:
- 分别用 FMM 和 BMM 对同一句话分词。
- 比较两个结果。
- 如果一致,直接输出。
- 如果不一致,按规则选一个。
选哪个?我常用的规则是:
- 选分词数量少的那个(颗粒度更粗)
- 如果数量一样,选单字词少的那个
- 如果还一样,选 BMM 的结果(个人偏好)
举个例子,句子是「他说的确实在理」:
FMM 结果:他 / 说的 / 确实 / 在理
BMM 结果:他 / 说 / 的确 / 实在 / 理
你看,两个结果不一样。FMM 切了 4 个词,BMM 切了 5 个。按规则,选词数少的 FMM 结果。这个结果也是正确的。
避坑指南: 我曾经在做一个新闻分类系统时,发现双向匹配法虽然准确率高了,但速度慢了一倍。如果你的系统对实时性要求很高,比如在线搜索,那就要权衡一下。我当时的做法是:先用 FMM 快速切,遇到置信度低的句子再启用双向匹配。
2.4 三种方法的对比
我把它们的核心差异整理成了一张表,方便你对比:
| 方法 | 扫描方向 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| FMM | 从左到右 | 速度快,实现简单 | 容易漏掉「偏正结构」 | 实时性要求高的场景 |
| BMM | 从右到左 | 准确率略高 | 速度与 FMM 相当 | 通用场景,推荐首选 |
| 双向 | 双向扫描 | 准确率最高 | 速度慢一倍 | 离线处理、精度优先 |
你想想看,这三种方法其实都没有用到任何「语言知识」。它们纯粹靠词典和匹配规则。说白了,就是暴力枚举。但为什么还要学?因为它们是理解更复杂分词技术的基础。
我个人习惯是,在项目初期先用双向最大匹配法搭一个基线系统。虽然它不够完美,但能快速验证整个流程。等后面再慢慢换成更高级的模型。
嗯,最后提醒一句:最大匹配法的效果,很大程度上取决于词典的质量。我见过太多人花大量时间调算法,却忽略了词典的维护。其实,把词典做精了,FMM 也能达到 95% 以上的准确率。