分词器核心原理:正向最大匹配、逆向最大匹配、双向最大匹配算法详解

说到分词,很多新手第一反应就是「用现成的库不就行了?」。嗯,这话没错,但你要是真在搜索引擎公司待过,就知道底层匹配算法才是分水岭。我当年刚接手搜索项目时,就被一个长尾查询搞到凌晨三点——后来发现,问题就出在匹配方向上。

今天咱们就把这三种经典算法掰开揉碎。说白了,它们都是基于词典的匹配方法,没有机器学习那么玄乎,但胜在稳定、可控、速度快。我个人习惯把这类算法称为「老黄牛型选手」——不出彩,但绝对靠谱。

一、正向最大匹配(FMM)

先讲最直观的。正向最大匹配,就是从句子左边开始,每次取尽可能长的词去词典里查。

具体步骤是这样的:

  1. 设定一个最大词长(比如5个字)
  2. 从句子开头取前5个字,去词典查
  3. 如果命中,就切出来;没命中,就减少一个字再查
  4. 重复直到句子结束

举个例子:「南京市长江大桥」

假设最大词长=5:

  • 取「南京市长江」→ 没命中
  • 取「南京市长」→ 命中!切出「南京市长」
  • 剩下「江大桥」→ 取「江大桥」→ 没命中
  • 取「江大」→ 没命中 → 取「江」→ 命中
  • 最后「大桥」→ 命中

结果:南京市长 / 江 / 大桥

你看,这个结果其实是有问题的。「南京市长江大桥」本意是地名,却被切成了「南京市长」。我在项目中遇到过类似案例,用户搜「南京市长江大桥旅游攻略」,结果召回了一堆「南京市长」相关的新闻,你说尴尬不尴尬?

我的经验:正向最大匹配对「偏正结构」的短语容易出错。比如「研究生命科学」会被切成「研究生 / 命科学」。如果你做的是学术搜索,这个坑一定要提前规避。

二、逆向最大匹配(RMM)

既然正向有问题,那反过来试试?逆向最大匹配就是从句子右边开始匹配。原理一模一样,只是方向反了。

还是那个例子:「南京市长江大桥」

  1. 从右边取5个字「长江大桥」→ 命中!切出
  2. 剩下「南京市」→ 取「南京市」→ 命中

结果:南京市 / 长江大桥

这次对了!为什么会这样?因为汉语里很多长词是「修饰语+核心词」的结构,核心词往往在右边。逆向匹配天然更倾向于保留右边的长词,所以对这类场景更友好。

我记得有一次做新闻标题分词,正向匹配把「美国总统特朗普」切成了「美国 / 总统特 / 朗普」,差点没把我笑死。换成逆向匹配后,结果就变成了「美国 / 总统 / 特朗普」——这才是人话。

注意:逆向匹配也不是万能的。比如「北京大学生」这个例子:

  • 正向:北京 / 大学生 ✅
  • 逆向:北京大学 / 生 ❌

你看,逆向匹配在这里反而错了。所以没有银弹,只有权衡。

三、双向最大匹配(BMM)

既然正向和逆向各有优劣,那干脆两个都用,然后选一个最好的?这就是双向最大匹配的思路。

核心规则:

  1. 分别用FMM和RMM对句子分词
  2. 如果结果一样,直接输出
  3. 如果不一样,按以下优先级选择:
    • 词数少的优先(切分粒度更粗)
    • 词数相同时,单字词少的优先
    • 还一样?选逆向结果(经验法则)