2、分词基础技术:正向最大匹配法(FMM)、逆向最大匹配法(BMM)、双向最大匹配法

聊到中文分词,我第一个想跟你聊的,就是这三种最经典的匹配方法。它们虽然看起来简单,但却是很多工业级分词系统的基石。说白了,没有它们打底,后面那些高大上的统计模型、深度学习模型,效果都会大打折扣。

我记得刚入行那会儿,带我的老工程师就跟我说:「别小看最大匹配法,它虽然笨,但稳。」后来我在做搜索日志分析时,确实体会到了这一点。好,咱们一个一个来看。

2.1 正向最大匹配法(FMM)

FMM 的思路非常直白:从左往右扫描句子,每次取尽可能长的词。

具体怎么做呢?

  1. 先准备一个词典,里面装着所有可能的词。
  2. 设定一个「最大词长」,比如 5 个字符。
  3. 从句子开头取 5 个字符,去词典里查。
  4. 查到了,就切出来,指针往后移 5 位。
  5. 没查到,就缩短一个字符,变成 4 个字符再查。
  6. 重复,直到切完整个句子。

我举个例子你就明白了。句子是:「我们在野生动物园玩」。

假设最大词长是 5:

  • 取「我们在野生」→ 没查到,缩短
  • 取「我们在野」→ 没查到,缩短
  • 取「我们在」→ 查到!切出来
  • 剩下「野生动物园玩」→ 取「野生动物园」→ 查到!切出来
  • 剩下「玩」→ 查到!切出来

结果就是:「我们 / 在 / 野生动物园 / 玩」

嗯,这里要注意:如果词典里没有「野生动物园」,只有「野生」和「动物」,那结果就会变成「我们 / 在 / 野生 / 动物园 / 玩」。你看,词典的质量直接决定了分词效果。

核心要点: FMM 是贪心算法,每次取最长匹配。优点是速度快,缺点是容易产生歧义。

2.2 逆向最大匹配法(BMM)

BMM 和 FMM 几乎一模一样,唯一的区别是:从右往左扫描。

为什么要这么做?

我在项目中遇到过这样一个坑:用 FMM 切「研究生命科学」,结果变成了「研究生 / 命 / 科学」。这明显不对,原意是「研究 / 生命 / 科学」。

但换成 BMM 呢?从右往左切:

  • 取「命科学」→ 没查到,缩短
  • 取「科学」→ 查到!切出来
  • 剩下「研究生」→ 查到!切出来
  • 剩下「研究」→ 查到!切出来

结果就是「研究 / 生命 / 科学」。完美!

为什么会这样?因为中文里很多歧义结构,比如「AB/C」和「A/BC」这种,BMM 往往能更好地处理「偏正结构」的歧义。我个人的经验是,BMM 在大多数场景下准确率比 FMM 高那么一两个百分点。

小技巧: 如果你只能选一种方法做快速分词,我建议优先选 BMM。它处理「动宾结构」和「偏正结构」的歧义时,表现通常更好。

2.3 双向最大匹配法

既然 FMM 和 BMM 各有优劣,那把它们结合起来呢?这就是双向最大匹配法。

做法很简单:

  1. 分别用 FMM 和 BMM 对同一句话分词。
  2. 比较两个结果。
  3. 如果一致,直接输出。
  4. 如果不一致,按规则选一个。

选哪个?我常用的规则是:

  • 选分词数量少的那个(颗粒度更粗)
  • 如果数量一样,选单字词少的那个
  • 如果还一样,选 BMM 的结果(个人偏好)

举个例子,句子是「他说的确实在理」:

FMM 结果:他 / 说的 / 确实 / 在理
BMM 结果:他 / 说 / 的确 / 实在 / 理

你看,两个结果不一样。FMM 切了 4 个词,BMM 切了 5 个。按规则,选词数少的 FMM 结果。这个结果也是正确的。

避坑指南: 我曾经在做一个新闻分类系统时,发现双向匹配法虽然准确率高了,但速度慢了一倍。如果你的系统对实时性要求很高,比如在线搜索,那就要权衡一下。我当时的做法是:先用 FMM 快速切,遇到置信度低的句子再启用双向匹配。

2.4 三种方法的对比

我把它们的核心差异整理成了一张表,方便你对比:

方法 扫描方向 优点 缺点 适用场景
FMM 从左到右 速度快,实现简单 容易漏掉「偏正结构」 实时性要求高的场景
BMM 从右到左 准确率略高 速度与 FMM 相当 通用场景,推荐首选
双向 双向扫描 准确率最高 速度慢一倍 离线处理、精度优先

你想想看,这三种方法其实都没有用到任何「语言知识」。它们纯粹靠词典和匹配规则。说白了,就是暴力枚举。但为什么还要学?因为它们是理解更复杂分词技术的基础。

我个人习惯是,在项目初期先用双向最大匹配法搭一个基线系统。虽然它不够完美,但能快速验证整个流程。等后面再慢慢换成更高级的模型。

嗯,最后提醒一句:最大匹配法的效果,很大程度上取决于词典的质量。我见过太多人花大量时间调算法,却忽略了词典的维护。其实,把词典做精了,FMM 也能达到 95% 以上的准确率。