上一篇主要讨论了词典分词。词典分词可以解决“字符串能否成词”的问题,但无法很好处理切分歧义。例如“研究生命起源”既可以切成“研究 / 生命 / 起源”,也可以切成“研究生 / 命 / 起源”。两条路径可能都能在词典中找到对应词语,因此还需要一个标准来判断哪一种切分更合理。
二元语法模型(Bigram Language Model)正是这种标准中最基础的一种。它利用相邻两个词的共现概率,对候选切分路径进行打分。
问题定义
设一句话对应的分词结果为:
W = w1, w2, ..., wn
理想情况下,我们希望选择概率最大的那条切分路径:
W* = arg max P(W)
其中 P(W) 表示该词序列作为自然语言出现的概率。
但直接估计:
P(w1, w2, ..., wn)
几乎不可行,因为词序列空间过大,语料中很难覆盖所有组合。因此需要对联合概率进行近似建模。
马尔可夫假设与二元语法
由链式法则可得:
P(w1, w2, ..., wn) = P(w1) P(w2|w1) P(w3|w1,w2) ... P(wn|w1,...,wn-1)
若采用一阶马尔可夫假设,即认为当前词只依赖于前一个词,则有:
P(wi|w1,...,wi-1) ≈ P(wi|wi-1)
于是整句概率近似为:
P(W) ≈ P(w1) ∏(i=2..n) P(wi|wi-1)
这就是二元语法模型。它的核心在于估计条件概率 P(wi|wi-1)。
参数估计
设:
C(wi-1, wi)表示二元词对(wi-1, wi)在语料中的出现次数C(wi-1)表示词wi-1在语料中的出现次数
则最大似然估计为:
P(wi|wi-1) = C(wi-1, wi) / C(wi-1)
句首词的概率可以写为:
P(w1) = C(w1) / N
其中 N 为语料中的总词数,或者也可以显式加入句子起始标记 <BOS>,把首词概率改写为:
P(w1|<BOS>)
在实现中,加入 <BOS> 和 <EOS> 往往更统一,也更方便写动态规划。
为什么二元语法适合中文分词
中文分词的本质,是在一个句子对应的多条候选切分路径中找到最优路径。词典告诉我们“哪些片段可能是词”,二元语法告诉我们“哪些词连接在一起更自然”。
例如句子:
南京市长江大桥
候选切分可以写成:
南京市 / 长江大桥南京 / 市长 / 江大桥
若单看词典,第二条路径未必在形式上完全非法;但从统计语言模型角度看:
P(长江大桥|南京市)
通常远大于:
P(市长|南京) * P(江大桥|市长)
因此第一条路径会获得更高得分。
分词中的打分函数
在中文分词任务中,我们最终想求的是:
W* = arg max [P(w1) ∏(i=2..n) P(wi|wi-1)]
由于多个小概率连乘容易造成数值下溢,实际中通常取对数:
W* = arg max [log P(w1) + Σ(i=2..n) log P(wi|wi-1)]
等价地,也可以写成最小化负对数形式:
W* = arg min [-log P(w1) - Σ(i=2..n) log P(wi|wi-1)]
这样一来,中文分词就转化成了一个路径搜索问题:
- 节点表示候选词
- 边表示相邻词之间的转移
- 边权由
-log P(wi|wi-1)给出 - 最终寻找总代价最小的路径
这个过程可以结合 DAG、动态规划或 Viterbi 算法来完成。
一个简单例题
考虑句子:
商品和服务
假设词典给出的两条候选路径为:
商品 / 和 / 服务商 / 品和 / 服务
进一步假设语料统计如下:
C(商品) = 100C(和) = 200C(服务) = 150C(商品, 和) = 80C(和, 服务) = 120C(商, 品和) = 1C(品和, 服务) = 0
则有:
P(和|商品) = 80 / 100 = 0.8
P(服务|和) = 120 / 200 = 0.6
于是路径 1 的条件概率部分约为:
0.8 * 0.6 = 0.48
而路径 2 中,由于:
P(服务|品和) = 0
所以整条路径概率直接变为 0。可见二元语法会明显偏向第一种更自然的切分结果。
平滑
上述估计有一个经典问题:数据稀疏。若某个二元词对没有在训练语料中出现,则最大似然估计给出的概率为 0:
P(wi|wi-1) = 0
这会导致只要路径中有一条未见过的转移,整条路径概率就归零。为了缓解这个问题,需要做平滑。
最简单的方式是加一平滑:
P(wi|wi-1) = (C(wi-1, wi) + 1) / (C(wi-1) + |V|)
其中 |V| 表示词表大小。
虽然加一平滑并不是最优方法,但在课程练习或入门实现里,它足够直观。更常见、效果更好的方法还包括:
- Good-Turing
- Katz Backoff
- Kneser-Ney
与词典分词的结合
在工程实现中,二元语法通常不会单独工作,而是和词典匹配一起使用。一个典型流程如下:
- 使用词典或 Trie 枚举所有可能词语
- 构建句子的候选词图
- 用二元语法为相邻候选词赋予转移概率
- 使用动态规划寻找最优路径
因此可以把整个分词器理解为两层:
- 词典层负责“召回候选词”
- 语言模型层负责“排序候选路径”
上一篇偏重第一层,这一篇偏重第二层。
局限性
二元语法模型虽然简单有效,但它有明显的表达上限。
- 只考虑前一个词,无法建模更长距离的依赖
- 对语料规模较敏感,小语料下统计不稳定
- 对未登录词仍然不够友好
例如有些歧义需要结合更长上下文才能解决,这时二元语法往往不够,需要进一步引入:
- 三元语法
- HMM
- CRF
- 神经网络语言模型
小结
二元语法的核心思想可以概括为一句话:用相邻词的共现概率来近似刻画整条分词路径的合理性。
其基本公式为:
P(W) ≈ P(w1) ∏(i=2..n) P(wi|wi-1)
在中文分词中,我们并不是单纯判断“某个片段是不是词”,而是在所有候选切分路径中寻找概率最大的那一条。因此,二元语法实际上把中文分词从“字符串匹配问题”推进成了“统计建模 + 路径搜索问题”。
继续往后学习时,一个自然的问题就是:如何把二元语法与 Viterbi 解码结合,真正实现一个可运行的统计分词器。