N-gram 语言模型
N-gram 语言模型在训练语料中查找相同的近期历史,统计后面出现的 token,用频次预测下一个 token。阶数 n 决定保留多少上下文。平滑能在计数为零时给出概率分布,但不能补出上下文证据。
这里没有隐藏向量或神经网络。每个预测都能从查询追溯到语料匹配、整数计数和概率。它适合作为可核查的基线,也可用于范围有限的任务。历史越长,上下文越具体;有限语料却越难覆盖这些历史。
工作原理
N-gram 是连续 n 个 token。预测时,模型取末尾 n - 1 个 token 作为历史 h,再统计每次完整匹配后紧接的 token w。
4-gram 对前缀 at dusk the cat 使用 h = dusk the cat。dusk 之前的词不参与预测。如果语料匹配三次,其中两次后接 sat,一次后接 ate,最大似然估计为:
P(sat | dusk the cat) = 2 / 3
P(ate | dusk the cat) = 1 / 3
词表中其余 token 的概率为零。一般形式是:
P(w | h) = C(h, w) / C(h)
C(h,w) 是历史后接 w 的次数。C(h) 是这个历史的后续 token 总数,即所有 C(h,w) 之和,不是整个语料的长度。每句末尾加入 <eos>,让句子结束也成为可预测的事件。
平滑与证据
最大似然给未见后续项分配零概率。评价一句话时,只要目标序列有一个这样的后续项,整句概率就变成零。加 alpha 平滑先给词表中每个 token 加相同的伪计数,再归一化:
P_alpha(w | h) = (C(h, w) + alpha) / (C(h) + alpha |V|)
分母必须加入 alpha |V|,因为共有 |V| 个候选。只改分子会破坏概率和为一的条件。调整后计数为 0.1,不代表语料观察到了 0.1 次;未见历史也不会因此获得证据。
逐步演示
默认设置是 n = 4、alpha = 0.1,训练语料如下。英文 token 是实验数据,保留原样。
| 句子 | 训练序列 |
|---|---|
| 1 | at dusk the cat sat <eos> |
| 2 | at dusk the cat sat <eos> |
| 3 | at dusk the cat ate <eos> |
| 4 | at dawn the dog slept <eos> |
| 5 | by noon the cat slept <eos> |
词表按首次出现排序,共 12 项:at、dusk、the、cat、sat、<eos>、ate、dawn、dog、slept、by、noon。
- 截取历史。 前缀是
at dusk the cat,4-gram 只取末尾三个 token:dusk the cat。 - 完整匹配。 第 1、2、3 句匹配。前两句后接
sat,第三句后接ate。第 4、5 句虽有相同的词,却没有这个完整历史。 - 计数。
sat: 2、ate: 1,其余十项为零。C(h) = 3,最大似然概率分别为0.6667和0.3333。 - 平滑。 分母变成
3 + 0.1 × 12 = 4.2。
| 后续项 | 观测次数 | 调整后计数 | 概率 |
|---|---|---|---|
sat | 2 | 2.1 | 0.5000 |
ate | 1 | 1.1 | 0.2619 |
| 其余每项 | 0 | 0.1 | 0.0238 |
概率总和仍为一。已见项让出一部分概率,分给未见项。
- 改一个词。 将
dusk改成dawn,前缀为at dawn the cat,历史为dawn the cat。每个词都在词表中,但这个历史从未出现。词表覆盖不等于上下文覆盖。 - 处理零计数。
C(dawn the cat) = 0。最大似然出现0/0,没有定义;十二个零也不是概率分布。平滑后,每项分子为0.1,分母为1.2,概率都是1/12 = 0.0833。分布有效,但没有区分候选的证据。 - 缩短历史。 改为 3-gram,历史变成
the cat。它出现四次:后接sat两次,ate、slept各一次。分母为4 + 0.1 × 12 = 5.2。概率为sat: 0.4038、ate: 0.2115、slept: 0.2115,其余九项各0.0192。模型重新找到证据,却不再区分黄昏、黎明和中午的上下文。
长历史为何稀疏
Unigram 的历史为空,因此全语料的 30 个 token 位置都参与计数,包括五个 <eos>。Bigram 看前一个 token,trigram 看前两个,4-gram 看前三个且要求顺序一致。
增加 n 有两面:dusk the cat 能排除 by noon the cat slept,让 sat 更突出;dawn the cat 却没有任何匹配,缩短为 the cat 才能找回四个样本。可能的历史数约为 |V|^(n - 1),语料提供的位置有限,这就是稀疏问题。
平滑改变固定历史下的估计;缩短历史改变哪些语料位置算作证据。前者不能替代后者。神经语言模型用向量表示 token 和上下文,让相似历史共享统计信息,不必逐字相同。N-gram 的优势则是每次计数都有出处。
选择 n 和 alpha
n = 1 忽略查询,只看全局频次;n = 2、3、4 分别保留末尾一、二、三个 token。较小的正 alpha 消除硬零,又保留频次差异;alpha 增大时,分布趋向均匀。默认已见历史中,把 alpha 从 0.1 调到 1.0,P(sat|h) 从 0.5000 降为 3/15 = 0.2000。它仍排第一,但两个真实观测的影响减小。
没有通用的最佳组合。更大的语料可支持更长历史;小语料往往需要短历史或回退。加 alpha 适合教学和基线。实际计数模型还会使用插值、回退、折扣和 Kneser–Ney 平滑,利用不同上下文长度和词频结构。
在留出数据上选择参数,比较平均负对数似然(交叉熵)或其指数形式困惑度。分词、词表和评价集须一致,数值越低越好。训练拟合改善而留出困惑度恶化,说明模型对已给计数的适应没有转化为泛化能力。
边界情况
- 未见历史且
alpha = 0:分母为零,最大似然无定义,不能显示为全零分布。 - 未见历史且
alpha > 0:alpha 在分子、分母中约掉,每项恒为1/|V|。 - 已见历史后的未见 token:最大似然为零,平滑给正概率:它把每项概率拉向均匀的
1 / |V|,高频项降低,低频的已见项可能升高。 - Unigram:包括
<eos>在内的每个语料位置都计数,查询内容不影响结果。 - 句末历史:
<eos>提供结束事件;没有它,句末这次出现就没有后续项可计数。 - 词表外输入:本课查询都在固定词表内。实际系统需要
<unk>策略,或能把任意输入映射到已知单位的分词器。 - 大小写和标点:若预处理没有统一,
Cat、cat、cat,和分开标点后的 token 序列不同。
常见错误
- 统计句中任意位置的词。只有完整历史后紧接的 token 才算后续项,部分匹配不算。
- 无论
n多大都使用整个前缀。3-gram 只看the cat,此时改dusk或dawn不影响预测。 - 用句子数或总 token 数作分母。每个历史有自己的
C(h)。 - 只给已见项加 alpha。平滑必须覆盖词表中的所有候选。
- 把伪计数当观测。它不增加语料匹配,也不证明未见项在该上下文中合理。
- 认为
n越大越好。没有足够覆盖时,更长历史反而更脆弱。 - 把均匀回退当成有根据的判断。候选并列,是因为当前历史没有证据。
简化范围
本课使用五句话、按首次出现建立的固定词表、空白分词和句末 <eos>。阶数为 1–4,alpha 为 0–1,便于手算。未展示未知词、大小写规则、标点拆分、句首标记、剪枝、多阶插值或留出集调参。
实际计数模型常结合多个历史长度,并用折扣与回退利用词在不同上下文中的出现情况。神经模型用学习到的表示替代精确历史表,但最终仍生成下一个 token 的概率分布。本课集中展示历史长度与证据覆盖之间的取舍。