NLP | 自然语言处理 - 语言模型(Language Modeling)

为什么需要语言模型?

想象“语音识别”这样的场景,机器通过一定的算法将语音转换为文字,显然这个过程是及其容易出错的。例如,用户发音“Recognize Speech”,机器可能会正确地识别文字为“Recognize speech”,但是也可以不小心错误地识别为“Wrench a nice beach”。简单地从词法上进行分析,我们无法得到正确的识别,但是计算机也不懂语法,那么我们应该如果处理这个问题呢?一个简单易行的方法就是用统计学方法(马尔可夫链)从概率上来判断各个识别的正确可能性。

什么是语言模型?

首先,我们定义一个有限的字典V。V = {the, a, man, telescope … },通过字典间有限或者无限次笛卡儿积,我们可以得到一个无限的字符串组合S,S可能包含:

1,the

2,a

3,the man

4,the man walks

其次,假设我们有一个训练数据集,数据集中包含了许多文章。通过统计数据集中出现的句子、其出现次数c(x)以及数据集句子总数N,我们可以计算出每个句子的出现频率。令x ∈ S,p(x) = c(x)/N表示x的出现频率,显然Σp(x) = 1。

综上所述,我们可以发现几个问题:

1)上述的语言模型只是理论上存在的,当训练数据集无限大的时候,数据集中的频率可以无限接近语法中实际的概率;

2)对于S中的大部分句子,p(x)应当等于0,因此S是一个非常稀疏的数据集,很难存储。

马尔可夫链

既然上面这个简单的语言模型不太完美,我们自然需要寻找其他的方法来获得语言模型,其中一个比较著名的算法就是马尔可夫链。假如考虑一个长度为n的句子可以利用一串随机变量来表示,即x1, x2, … xn,其中xk ∈ V。那么,我们的目标是求p(X1 = x1, X2 = x2, …, Xn = xn)。

显然,p(X1 = x1, X2 = x2, …, Xn = xn) = p(X1 = x1) * p(X2 = x2 | X1 = x1) * p(X3 = x3 | X1 = x1, X2 = x2) * … * p(Xn = xn | X1 = x1, X2 = x2, … Xn-1 = xn-1)。当n过大的时候,条件概率的复杂度会大大地增加,是否能够找到一个近似的方法方便求出这些条件概率呢?答案是肯定的,我们需要做一个假设,即每个单词这个随机变量只与前k个随机变量相关。

  • 一阶马尔可夫链

一阶马尔可夫链中我们认为每个单词这个随机变量只与前一个随机变量相关,因此上述表达式可以简化为p(X1 = x1, X2 = x2, …, Xn = xn) = p(X1 = x1) * p(X2 = x2 | X1 = x1) * p(X3 = x3 | X2 = x2) * … * p(Xn = xn | Xn-1 = xn-1) = p(X1 = x1) * ∏p(Xk = xk | Xk-1 = xk-1)

  • 二阶马尔可夫链

二阶马尔可夫链中我们认为每个单词这个随机变量只与前两个随机变量相关,因此上述表达式可以简化为p(X1 = x1, X2 = x2, …, Xn = xn) = p(X1 = x1) * p(X2 = x2 | X1 = x1) * p(X3 = x3 | X1 = x1, X2 = x2) * … * p(Xn = xn | Xn-2 = xn-2, Xn-1 = xn-1) = p(X1 = x1) * p(X2 = x2 | X1 = x1) * ∏p(Xk = xk | Xk-2 = xk-2, Xk-1 = xk-1)

通常长度n不是固定的,并且为了表述方便,我们可以做一些细节的优化。 1)增加一个开始符号”*“,我们定义所有句子都是以”*“开始,即X-1 = X0 = *; 2)增加一个结束符号”STOP“,我们定义所有句子都是以”STOP“结束。 综上所述,马尔可夫链表达式可以简化为: 一阶马尔可夫链:p(X1 = x1, X2 = x2, …, Xn = xn) = ∏p(Xk = xk | Xk-1 = xk-1)

二阶马尔可夫链:p(X1 = x1, X2 = x2, …, Xn = xn) = ∏p(Xk = xk | Xk-2 = xk-2, Xk-1 = xk-1)

二阶马尔可夫的语言模型

有了二阶马尔可夫,我们可以重新定义一下语言模型: 1)一个有限的字典V 2)对于每个Trigram(三个连续的词)定义一个参数q(w | u, v),w∈ V ∪ {STOP},u, v ∈ V ∪ {*} 3)对于任意句子x1, x2, … xn,其中x-1 = x0 = *,xn = STOP,xk(k = 1, 2, …, n-1)∈ V,句子的出现概率p(x1, x2, … xn) = ∏q(Xk = xk | Xk-2 = xk-2, Xk-1 = xk-1)

举个例来讲,对于句子the dog barks STOP,我们可以做如下分析: p(the dog barks STOP) = q(the | *, *) * q(dog | *, the) * q(barks | the, dog) * q(STOP | dog, barks)

二阶马尔可夫的语言模型的计算

计算二阶马尔可夫的语言模型似乎变成了一个简单的统计问题,通过在训练数据集中统计连续三个词的出现次数c(u, v, w)和两个词的出现次数c(u, v),q(w | u, v) = c(u, v, w) / c(u, v)。

算法到了这里看起来挺完美了,如果有一个不错的训练数据集,我们就可以训练出语言模型了。但是上文我们还提到一个问题,即训练数据集的稀疏性。只有数据集无限大的时候我们才能保证所有可能出现的句子都被语言模型包含,否则我们无法获得可靠的语言模型。另外,倘若任意一个Trigram(三个连续的词)对应的q(w | u, v) = 0,我们将灾难性地获得句子的概率等于0。

现实生活中,我们无法获得无限大的训练数据集,因为我们希望找到一个近似的算法来是所有的Trigram(三个连续的词)对应的q(w | u, v)都不为0,同时尽可能地找到与事实接近的q(w | u, v)。一种常见的方法是利用Unigram(单个词)、Bigram(两个词)、Trigram(三个词)来做近似的计算。

Unigram:q'(w) = c(w) / c()

Bigram:q'(w | v) = c(v, w) / c(v)

Trigram:q'(w | u, v) = c(u, v, w) / c(u, v)

我们定义q(w | u, v) = k1 * q'(w | u, v) + k2 * q'(w | v) + k3 * q'(w),其中k1 + k2 + k3 = 1,ki >= 0。

首先,我们需要证明Σq(w | u, v) = 1。即Σq(w | u, v) = Σ[k1 * q'(w | u, v) + k2 * q'(w | v) + k3 * q'(w)] = k1 * Σq'(w | u, v) + k2 * Σq'(w | v) + k3 * Σq'(w) = k1 * 1 + k2 * 1 + k3 * 1 = k1 + k2 + k3 = 1。

其次,我们应该如果确定k1, k2与k3呢?利用类似交叉熵(Cross Entropy)的方法,我们可以让q(w | u, v)尽量接近训练集中的统计结果。假设c'(u, v, w)是从测试集中统计出的Trigram(三个词)的出现次数,L(k1, k2, k3) = Σc'(u, v, w) * log[q(w | u, v)]。满足L(k1, k2, k3)最大化的临界点便能确定k1, k2, k3。

二阶马尔可夫的语言模型的度量:复杂度(Perplexity)

假设我们有一个测试数据集(共M个句子),每个句子si对应一个概率p(si),因此测试数据集的概率积为∏p(si)。经过简化,我们可以得到log∏p(si) = Σlog[p(si)]。Perplexity = 2^-l,其中l = 1 / M Σlog[p(si)]。(类似熵的定义)

几个直观的例子:

1)假设q(w | u, v) = 1/ M,Perplexity = M;

2)|V| = 50000的数据集的Trigram模型,Perplexity = 74;

3)|V| = 50000的数据集的Bigram模型,Perplexity = 137;

4)|V| = 50000的数据集的Unigram模型,Perplexity = 955。

点赞