第一部分 · 预测下一个词

给没见过的搭配留一点可能性

训练材料里没出现过,不代表以后不会出现。平滑方法会为这些词语搭配留出一部分概率。

给没见过的情况,也留一点概率 Lec 3 · Sep 1 · Lec 4 · Sep 3 回顾

如果训练文本里没有 “denied the offer”,只按原始次数估计的模型就会把这个后续算成零概率。但样本中没有出现,并不足以说明这种表达永远不可能出现。

即使词表很小,也会遇到这个问题。假设词表是 I, like, to, eat, cake, but, want, pizza, right, now, ., Mary, told, her, brother, too。有 \(|V|\) 个不同的词,就有 \(|V|^2\) 种可能的相邻词对,而一小份训练文本会遗漏其中的大部分。

平滑(smoothing)就是调整直接从计数得到的概率:从见过的情况中分出一点,留给暂时没见过的情况。

总量不变,但多照顾几种可能
“denied the”后面的原始计数调整后的示意计数
3 allegations
2 reports
1 claims
1 request
共 7
2.5 allegations
1.5 reports
0.5 claims
0.5 request
2 other
共 7

总量仍然是 7,但现在有 2 份留给其他后续词。除以相同的总量之后,得到的概率分布就给未见情况留下了空间。这张表只是在说明平滑的思路,并不是下文加一法的具体计算。

为什么数据再多,也总有很多低频词? Lec 3 · Sep 1

有些词不断重复,另一些词却只出现几次。这种不均匀的分布可以用齐普夫定律(Zipf's law)描述。Zipf 在 1949 年的著作 Human behavior and the principle of least effort 中讨论了这种幂律关系。

把词按出现频率从高到低排列,频率大致按下面的规律下降:

\[ \text{freq}_w(r) \propto r^{-s}, \qquad s \text{ 为常数} \]

其中 \(r\) 是词的频率排名。少数高频词占去大部分出现次数,后面跟着大量低频词,形成很长的“尾巴”。因此,自然语言处理方法必须能应对训练样本中很少出现、甚至完全没有出现的情况。

最简单的办法:每个计数都加一 Lec 3 · Sep 1 · Lec 4 · Sep 3 回顾

一个经典办法是加一平滑(add-one smoothing),也叫拉普拉斯平滑(Laplace smoothing)。我们假装每个可能的词都比实际多出现了一次:原来为零的计数变成 1,其他计数也都加 1。

分母也必须跟着增加。下面公式中的 \(V\) 表示词表大小;给每个可能结果各加一次,总计数就一共增加了这么多次。

一元模型:比较原始估计与加一后的估计
\[ P_{\text{MLE}}(w_i) = \frac{c(w_i)}{\sum_w c(w)} \qquad\qquad P_{\text{Add-1}}(w_i) = \frac{c(w_i) + 1}{\sum_w \big(c(w) + 1\big)} = \frac{c(w_i)+1}{V + \sum_w c(w)} \]
二元模型:对同一上下文的每个候选后续词都加一次
\[ P_{\text{MLE}}(w_i \mid w_{i-1}) = \frac{c(w_{i-1} w_i)}{c(w_{i-1})} \qquad\qquad P_{\text{Add-1}}(w_i \mid w_{i-1}) = \frac{c(w_{i-1} w_i) + 1}{c(w_{i-1}) + V} \]

如果只增加分子、不增加分母,所有候选词的概率加起来就会超过 1。分母中的 \(+V\) 正好补上新增的计数,让总概率仍然等于 1。

餐馆查询的概率表会怎样变化?

对 Berkeley Restaurant Corpus 的相邻词对计数表应用加一法后,每个零变成 1,其他格子也各加 1。然后用增大后的行总数作分母,即 \((c+1)/(c(w_{i-1})+V)\),其中 \(V = 1446\)。

换回原来的计数尺度,看看改动有多大

“每个格子只加一”听起来变化不大。要看清实际影响,可以把平滑后的概率再乘以原来的上下文次数。得到的 \(c^*\) 叫重构计数(reconstituted count),表示原来的总次数如果按新概率分配,这个词对相当于还能分到多少次。

\[ c^*(w_{i-1} w_i) = \frac{\big[c(w_{i-1} w_i) + 1\big] \cdot c(w_{i-1})}{c(w_{i-1}) + V} \]

结果变化很明显:want to 从原来的 608 次降到约 238 次,chinese food 从 82 次降到约 8.2 次。虽然每个格子只增加了一次,但原先为空的格子太多,合在一起拿走了很大一部分概率。

如果加一太多,就少加一点

加 k 平滑(add-k smoothing)沿用相同的办法,只是把增加的次数改成一个选定的正数,通常小于一,例如 0.5、0.05 或 0.01:

\[ P_{\text{Add-}k}(w_i \mid w_{i-1}) = \frac{c(w_{i-1} w_i) + k}{c(w_{i-1}) + kV} \]

这里的 \(k\) 是超参数(hyperparameter),也就是需要通过实验选择的设置。通常用另外留出的验证集来选它:先看哪种平滑强度能更好地预测新数据,再进行最终测试。

容易计算,不代表适合所有任务

课件不建议在实际的词组语言模型中使用加一法,因为未见组合太多,它可能分走过多概率。不过,在朴素贝叶斯文本分类,以及零计数没那么多的问题里,加一法仍然有用。加 k 法能更细地控制改动大小,但它仍然给每个候选结果增加相同的计数。

把长上下文和短上下文的判断合起来 Lec 3 · Sep 1

假设我们对一个两词上下文了解很少,但可能已经知道它最后一个词后面通常接什么,也知道候选词在整份语料中有多常见。与其对所有未见后续一视同仁,不如把这些较短上下文提供的证据也用上。

插值(interpolation)就是把不同长度的预测混合起来。三元模型可以结合一元、二元和三元概率;更一般地,可以从 n 元、n−1 元一直结合到一元估计。课件将它作为通常比加一法更有效的办法。

线性插值:给三种估计分配权重,再相加
\[ \hat P(w_n \mid w_{n-2} w_{n-1}) = \lambda_1 P(w_n) + \lambda_2 P(w_n \mid w_{n-1}) + \lambda_3 P(w_n \mid w_{n-2} w_{n-1}), \qquad \sum_i \lambda_i = 1 \]
根据上下文调整权重:不同前文可以采用不同的组合比例
\[ \hat P(w_n \mid w_{n-2} w_{n-1}) = \lambda_1(w_{n-2}^{\,n-1})\, P(w_n) + \lambda_2(w_{n-2}^{\,n-1})\, P(w_n \mid w_{n-1}) + \lambda_3(w_{n-2}^{\,n-1})\, P(w_n \mid w_{n-2} w_{n-1}) \]

各个 λ 权重必须非负,而且加起来等于一,这样混合结果才仍然是概率分布。第二个公式让权重随上下文变化:见过很多次的上下文,与证据很少的上下文,可以采用不同的比例。

用单独留出的文本选择权重

我们希望选出的权重能够给新文本较高概率,而这份文本不能是之前用来估计计数的同一份数据:

  1. 先用训练集估计各阶词组概率,然后固定这些估计值。
  2. 搜索能让验证集概率最大的 λ。

其他超参数也遵循同样的分工,包括加 k 法中的 \(k\):训练集负责学习计数,验证集负责选择设置,测试集留到最后评估。

根据已有文本,决定能看多长的上下文 Lec 3 · Sep 1

第 3 讲还介绍了 infini-gram 的思路:不预先固定一个上下文长度,而是在语料中寻找能够匹配的最长上下文,必要时再缩短。课件把它描述为原则上允许 \(n = \infty\);实际使用的上下文长度仍然受已观察文本限制。

  • 课件讨论了用 Dolma、RedPajama、Pile、C4 等开放文本集合构建的模型。这些语料也用于训练大语言模型。
  • 它们可以用来检索词组、查询出现次数和概率,也可以用于文本生成。
本页要记住什么
  • 低频和未见事件是语言数据的常态。预测新文本时,模型需要有办法应对它们。
  • 加一法和加 k 法容易计算,但统一增加计数的方式可能不适合很稀疏的词组表;它们在朴素贝叶斯等场景中仍然有用。
  • 插值借助较短上下文的估计。它的权重,以及其他超参数,都应在验证集上选择,不要用测试集调参。
  • 平滑帮助词组模型减少对训练计数的过度依赖;正则化则在逻辑回归等模型中处理同一类过拟合问题。