Week2.1 Language modeling: It's all about counting!

Language Modeling

本周将学习语言模型,NLP核心的部分。首先会接触一些语言模型,然后学习一些序列模型,例如part-of-speech tagging or named-entity。这些任务都非常有用的基础功能。

1.Count! N-gram language models

当你看到一个句子的开头,你将如何往下接呢?作为人类,我们有一些自己的直觉,或者说是语感。我们根据自身的经历和积累能够预测接下来会说些什么。但是机器不能做到这点。所以我们想要构造一种模型来实现这种预测。

For Bigram

对于给出的词,我们能否预测下一个词是什么呢?这当然是容易做到的一点。首先我们会有一个语料库。我们将在这个语料库上来进行操作。

对于每一个自然语言的句子 s s s,它可以由任意的字符来构成。例如:

  • Sentence 1 = I will write a blog after I finished today’s MOOC.
  • Sentence 2 = I MOOC a finished blog will write today’s after I.

我们从上面的句子可以看到,对于英语来说, S e n t e n c e 1 Sentence 1 Sentence1是一个由明确语义的句子,而 S e n t e n c e 2 Sentence 2 Sentence2并不是。从一个句子是否会出现的概率上来讲,我们明显可以感觉到 P ( S e n t e n c e 1 ) > P ( S e n t e n c e 2 ) P(Sentence1)>P(Sentence2) P(Sentence1)>P(Sentence2)
同样的,预测下一个词出现的概率也是如此。基于语料库,如果我们知道更多这个句子片段的更多信息,我们就能对接下来的词进行更好的预测。

Chain rule

对于k个词组成的序列 w 1 , w 2 , ⋯ , w k w_1,w_2,⋯,w_k w1,w2,,wk ,根据链式规则,它出现的概率为
P ( w 1 , w 2 , ⋯ , w k ) = P ( w 1 ) P ( w 2 ∣ w 1 ) P ( w 3 ∣ w 1 , w 2 ) ⋯ P ( w k ∣ w 1 , ⋯ , w k − 1 ) P(w_1,w_2,⋯,w_k)=P(w_1)P(w_2|w_1)P(w_3|w_1,w_2)⋯P(w_k|w_1,⋯,w_{k−1}) P(w1,w2,,wk)=P(w1)P(w2w1)P(w3w1,w2)P(wkw1,,wk1)
对于这最后一个条件概率,它显然太长了,计算会非常麻烦。我们当然想要偷懒 那么有没有什么方法来规避它呢?幸好,马尔可夫已经给出了解决方案。根据马尔可夫链假设,当前的词仅和它前面几个词相关,不需要一直考虑到最开始的那个词,即
P ( w i ∣ w 1 , ⋯ , w i − 1 ) = P ( w i ∣ w i − n + 1 , ⋯ , w i − 1 ) P(w_i|w_1,⋯,w_{i−1})=P(w_i|w_{i−n+1},⋯,w_{i−1}) P(wiw1,,wi1)=P(wiwin+1,,wi1)
这样我们就成功的将每个一个式子进行了化简

Models and Optimization

根据上面给出的结论,当n较小时,我们有如下结论:
n = 1 n=1 n=1, 我们有Unigram model
P ( w 1 , w 2 , ⋯ , w k ) = ∏ i = 1 k P ( w i ) P(w_1,w_2,⋯,w_k)=∏_{i=1}^kP(w_i) P(w1,w2,,wk)=i=1kP(wi)
n = 2 n=2 n=2, 我们有Bigram model
P ( w 1 , w 2 , ⋯ , w k ) = ∏ i = 1 k P ( w i ∣ w i − 1 ) P(w_1,w_2,⋯,w_k)=∏_{i=1}^kP(w_i|w_{i−1}) P(w1,w2,,wk)=i=1kP(wiwi1)

n = 3 n=3 n=3, 我们有Trigram model
P ( w 1 , w 2 , ⋯ , w k ) = ∏ i = 1 k P ( w i ∣ w i − 2 w i − 1 ) P(w_1,w_2,⋯,w_k)=∏_{i=1}^kP(w_i|w_{i−2}w_{i−1}) P(w1,w2,,wk)=i=1kP(wiwi2wi1)

Awesome!但是这样就完美了吗?让我们来看看Bigram的情况。

显然对于语料库中每一个句子的开头,我们都是已知的。每个开头单词都会有一个其作为开头概率,但是在公式中,我们使用一个 P ( w 1 ) P(w_1) P(w1)——对于所有词来说其出现的概率,来代替了其作为开头的概率,这里的偏差就非常大了。所以我们可以加上一个fake start来对这个偏差进行调整。也就是将 P ( w 1 ) P(w_1) P(w1)改为 P ( w 1 ∣ s t a r t ) P(w_1|start) P(w1start).

好的,我们刚刚解决了开头单词概率的问题。那么现在还有一个问题,所有这些n-gram的概率总和为1吗?显然不是。我们现在构造的结果是,每种n-gram的概率和是1;但是我们希望所有这些相加起来的概率是1.这就会比较符合我们的数学直觉了。

其实我们可以仿照上面我们的解决方案,对每个句子的结尾加上一个fake ending。也就是在公式的最后加上 P ( e n d ∣ w k ) P(end|w_k) P(endwk),这样我们就实现了归一化。

Resume: Bigram language model

对于公式,其中 c ( w 1 , . . , w k ) c(w_1,..,w_k) c(w1,..,wk) 表示 n-gram w 1 , . . , w k w_1,..,w_k w1,..,wk 在训练语料中出现的次数。
所以bigram model的最终公式为
P ( w i ∣ w i − 1 ) = C ( w i − 1 w i ) C ( w i − 1 ) P(w_i|w_{i−1})=\frac{C(w_{i−1}w_i)}{C(w_{i−1})} P(wiwi1)=C(wi1)C(wi1wi)
对于一整句话,我们有
P ( W ) = ∏ i = 1 k + 1 P ( w i ∣ w i − 1 ) P(W)=∏_{i=1}^{k+1}P(w_i|w_{i−1}) P(W)=i=1k+1P(wiwi1)

It’s all about counting!

2.Perplexity:is our model surprised with a real text?

3.Smoothing: what if we see new n-grams?

问题:概率为0

当我们在训练我们的模型时,进行测试的过程中,我们会发现有些n-grams从来没有出现过,这会导致一些问题。此时我们有一种解决的办法——Smoothing,平滑。

在实际运用中,Smoothing的方法有很多种,在MOOC中也都有提及,接下来就具体学习一下这些方法。
这里我要偷懒地直接搬运了,省出打字的时间来好好看看大佬们是给出的总结
https://blog.csdn.net/baimafujinji/article/details/51297802

Laplace Smoothing

Add-one是最简单、最直观的一种平滑算法。既然希望没有出现过的N-Gram的概率不再是0,那就不妨规定任何一个N-Gram在训练语料至少出现一次(即规定没有出现过的N-Gram在训练语料中出现了一次),则: c o u n t n e w ( n − g r a m ) = c o u n t o l d ( n − g r a m ) + 1 count_{new}(n-gram)=count_{old}(n-gram)+1 countnew(ngram)=countold(ngram)+1
于是,对于unigram模型而言,会有
P a d d 1 ( w i ) = C ( w i ) + 1 M + ∣ V ∣ P_{add1}(w_i)=\frac{C(w_i)+1}{M+|V|} Padd1(wi)=M+VC(wi)+1

其中, M M M 是训练语料中所有的N-Gram的数量(token),而 V V V 是所有的可能的不同的N-Gram的数量(type)。
同理,对于bigram模型而言,可得
P a d d 1 ( w i ∣ w i − 1 ) = C ( w i − 1 w i ) + 1 C ( w i − 1 ) + ∣ V ∣ P_{add1}(w_i|w_{i−1})=\frac{C(w_{i−1}w_i)+1}{C(w_{i−1})+|V|} Padd1(wiwi1)=C(wi1)+VC(wi1wi)+1

推而广之,对于n-Gram模型而言,可得
P a d d 1 ( w i ∣ w i − n + 1 , ⋯ , w i − 1 ) = C ( w i − n + 1 , ⋯ , w i ) + 1 C ( w i − n + 1 , ⋯ , w i − 1 ) + ∣ V ∣ P_{add1}(w_i|w_{i−n+1},⋯,w_{i−1})=\frac{C(w_{i−n+1},⋯,w_i)+1}{C(w_{i−n+1},⋯,w_{i−1})+|V|} Padd1(wiwin+1,,wi1)=C(win+1,,wi1)+VC(win+1,,wi)+1

例如,对于句子The rat ate the cheese,我们可以来试着计算一下经add-one平滑后的 P ( a t e ∣ r a t ) P(ate|rat) P(aterat)以及 P ( a t e ∣ c h e e s e ) P(ate|cheese) P(atecheese),即
P ( a t e ∣ r a t ) = C ( r a t a t e ) + 1 C ( r a t ) + ∣ V ∣ = 2 6 P(ate|rat)=\frac{C(ratate)+1}{C(rat)+|V|}=\frac{2}{6} P(aterat)=C(rat)+VC(ratate)+1=62
P ( a t e ∣ c h e e s e ) = C ( c h e e s e a t e ) + 1 C ( c h e e s e ) + ∣ V ∣ = 1 6 P(ate|cheese)=\frac{C(cheeseate)+1}{C(cheese)+|V|}=\frac{1}{6} P(atecheese)=C(cheese)+VC(cheeseate)+1=61

如此一来,训练语料中未出现的n-Gram的概率不再为 0,而是一个大于 0 的较小的概率值。Add-one 平滑算法确实解决了我们的问题,但显然它也并不完美。由于训练语料中未出现n-Gram数量太多,平滑后,所有未出现的n-Gram占据了整个概率分布中的一个很大的比例。因此,在NLP中,Add-one给训练语料中没有出现过的 n-Gram 分配了太多的概率空间。此外,认为所有未出现的n-Gram概率相等是否合理其实也值得商榷。而且,对于出现在训练语料中的那些n-Gram,都增加同样的频度值,这是否欠妥,我们并不能给出一个明确的答案。

Add-k Smoothing(Lidstone’s law)

由Add-one衍生出来的另外一种算法就是 Add-k。(根据上文中黑体部分)既然我们认为加1有点过了,不然选择一个小于1的正数 k。此时,概率计算公式就变成了
P a d d k ( w i ∣ w i − n + 1 ⋯ w i − 1 ) = C ( w i − n + 1 ⋯ w i ) + k C ( w i − n + 1 ⋯ w i − 1 ) + k ∣ V ∣ P_{addk}(w_i|w_{i−n+1}⋯w_{i−1})=\frac{C(w_{i−n+1}⋯w_i)+k}{C(w_{i−n+1}⋯w_{i−1})+k|V|} Paddk(wiwin+1wi1)=C(win+1wi1)+kVC(win+1wi)+k

通常,add-k算法的效果会比Add-one好,但是显然它不能完全解决问题。至少在实践中,k 必须人为给定,而这个值到底该取多少却莫衷一是。

回退(Backoff)

通常我们会认为高阶模型更加可靠,我们之前中给出的例子也表明,当能够获知更多历史信息时,其实就获得了当前推测的更多约束,这样就更容易得出正确的结论。所以在高阶模型可靠时,尽可能的使用高阶模型。但是有时候高级模型的计数结果可能为0,这时我们就转而使用低阶模型来避免稀疏数据的问题。

如果用公式来定义,即
P b a c k o f f ( w i ∣ w i − n + 1 ⋯ w i − 1 ) = { P ∗ ( w i ∣ w i − n + 1 ⋯ w i − 1 ) , i f C ( w i − n + 1 ⋯ w i ) > 0 α ( w i − n + 1 ⋯ w i − 1 ) ⋅ P b a c k o f f ( w i ∣ w i − n + 2 ⋯ w i − 1 ) , o t h e r w i s e P_{backoff}(w_i|w_{i−n+1}⋯w_{i−1})=\begin{cases} P∗(w_i|w_{i−n+1}⋯w_{i−1}) & ,ifC(w_{i−n+1}⋯w_i)>0\\ {α(w_{i−n+1}⋯w_{i−1})⋅P_{backoff}(w_i|w_{i−n+2}⋯w_{i−1})}&,otherwise\end{cases} Pbackoff(wiwin+1wi1)={P(wiwin+1wi1)α(win+1wi1)Pbackoff(wiwin+2wi1),ifC(win+1wi)>0,otherwise

其中 α α α P ∗ P∗ P 是归一化因子,以保证 ∑ P b a c k o f f = 1 ∑P_{backoff}=1 Pbackoff=1

插值(Interpolation)

插值和回退的思想其实非常相像。设想对于一个trigram的模型,我们要统计语料库中 “like chinese food” 出现的次数,结果发现它没出现过,则计数为0。在回退策略中,将会试着用低阶gram来进行替代,也就是用 “chinese food” 出现的次数来替代。

在使用插值算法时,我们把不同阶别的n-Gram模型线形加权组合后再来使用。简单线性插值(Simple Linear Interpolation)可以用下面的公式来定义:
P i n t e r p ( w n ∣ w n − 2 , w n − 1 ) = λ 1 P ( w n ) + λ 2 P ( w n ∣ w n − 1 ) + λ 3 P ( w n ∣ w n − 2 , w n − 1 ) P_{interp}(w_n|w_{n−2},w_{n−1})=λ_1P(w_n)+λ_2P(w_n|w_{n−1})+λ_3P(w_n|w_{n−2},w_{n−1}) Pinterp(wnwn2,wn1)=λ1P(wn)+λ2P(wnwn1)+λ3P(wnwn2,wn1)

其中, 0 ≤ λ i ≤ 1 0≤λ_i≤1 0λi1 ∑ i λ i = 1 ∑_iλ_i=1 iλi=1 λ i λ_i λi可以根据试验凭经验设定,也可以通过应用某些算法确定,例如EM算法。
在简单单线形插值法中,权值 λ i λ_i λi 是常量。显然,它的问题在于不管高阶模型的估计是否可靠(毕竟有些时候高阶的Gram计数可能并无为 0),低阶模型均以同样的权重被加入模型,这并不合理。一个可以想到的解决办法是让 λ i λ_i λi 成为历史的函数。如果用递归的形式重写插值法的公式,则有
P i n t e r p ( w i ∣ w i − n + 1 ⋯ w i − 1 ) = λ ( w i − n + 1 ⋯ w i − 1 ) ⋅ P ( w i ∣ w i − n + 1 ⋯ w i − 1 ) + ( 1 − λ ( w i − n + 1 ⋯ w i − 1 ) ) P i n t e r p ( w i ∣ w i − n + 2 ⋯ w i − 1 ) P_{interp}(w_i|w_{i−n+1}⋯w_{i−1})=λ(w_{i−n+1}⋯w_{i−1})⋅P(w_i|w_{i−n+1}⋯w_{i−1})+(1−λ(w_{i−n+1}⋯w_{i−1}))P_{interp}(w_i|w_{i−n+2}⋯w_{i−1}) Pinterp(wiwin+1wi1)=λ(win+1wi1)P(wiwin+1wi1)+(1λ(win+1wi1))Pinterp(wiwin+2wi1)

注意同样需要保证 ∑ P i n t e r p = 1 ∑P_{interp}=1 Pinterp=1。上面这个公式又称为Jelinek-Mercer Smoothing。而且,正如前面所展示的那样,λλ 可以是常数,而我们上式中 λ ( w i − n + 1 ⋯ w i − 1 ) λ ( w i − n + 1 ⋯ w i − 1 ) λ(w_{i−n+1}⋯w_{i−1})λ(w_{i−n+1}⋯w_{i−1}) λ(win+1wi1)λ(win+1wi1) 意思是表示 λ λ λ 是历史的一个函数,这通常是更明智的做法。

Absolute Discounting

想想之前的Add-one,以及Add-k算法。我们的策略,本质上说其实是将一些频繁出现的 N-Gram 的概率匀出了一部分,分给那些没有出现的 N-Gram 上。因为所有可能性的概率之和等于1,所以我们只能在各种可能的情况之间相互腾挪这些概率。

既然我们打算把经常出现的一些N-Gram的概率分一些出来,其实也就等同于将它们出现的次数减去(discount)一部分,那到底该discount多少呢?Church & Gale (1991) 设计了一种非常巧妙的方法。首先他们在一个留存语料库(held-out corpus)考察那些在训练集中出现了4次的bigrams出现的次数。具体来说,他们首先在一个有2200万词的留存语料库中检索出所有出现了4次的bigrams (例如: “chinese food”,“good boy”,“want to”等),然后再从一个同样有2200万词的训练集中,分别统计这些bigrams出现的次数(例如:C(“chinese food”)=4,C(“good boy”)=3,C(“want to”)=3)。最终,平均下来,他们发现:在第一个2200万词的语料中出现4次的bigrams,在第二个2200万词的语料中出现了3.23次。下面这张表给出了 c 从0到9取值时(也就是出现了 c 次),统计的bigrams在留存集和训练集中出现的次数。
在这里插入图片描述

其实你应该已经发现其中的规律了。除了计数为0和为1的bigram之外,held-out set中的平均计数值,都大约相当于training set中的计数值减去0.75。

基于上面这个实验结果所诱发的直觉,Absolute discounting 会从每一个计数中减去一个(绝对的)数值 dd。这样做的道理就在于,对于出现次数比较多的计数我们其实已经得到了一个相对比较好的估计,那么当我们从这个计数值中减去一个较小的数值 dd 后应该影响不大。上面的实验结果暗示在实践中,我们通常会对从2到9的计数进行处理。
P A b s D i s c o u n t ( w i ∣ w i − 1 ) = C ( w i − 1 w i ) − d C ( w i − 1 ) + λ ( w i − 1 ) P ( w i ) P_{AbsDiscount}(w_i|w_{i−1})=\frac{C(w_{i−1}w_i)−d}{C(w_{i−1})}+λ(w_{i−1})P(w_i) PAbsDiscount(wiwi1)=C(wi1)C(wi1wi)d+λ(wi1)P(wi)

从上一段中,我们已经知道,对于bigram model而言, P ( w i ∣ w i − 1 ) = C ( w i − 1 w i ) / C ( w i − 1 ) P(wi|wi−1)=C(w_{i−1}w_i)/C(w_{i−1}) P(wiwi1)=C(wi1wi)/C(wi1),所以上述方程等号右侧第一项即表示经过 discounting 调整的概率值,而第二项则相对于一个带权重 λλ 的 unigram 的插值项。通常,你可以把 d d d值就设为 0.75,或者你也可以为计数为 1 的 bigram 设立一个单独的等于 0.5 的 d d d 值(这个经验值从上面的表中也能看出来)。

Kneser-Ney Smoothing

这种算法目前是一种标准的,而且是非常先进的平滑算法,它其实相当于是前面讲过的几种算法的综合。由于这个算法比较复杂,我们从一个直观上的例子来开始。

假设我们使用 bigram 和 unigram 的插值模型来预测下面这个句子中空缺的一个词该填什么

  • I used to eat Chinese food with ______ instead of knife and fork.

直觉上你一定能猜到这个地方应该填 chopsticks(筷子)。但是有一种情况是训练语料库中,Zealand 这个词出现的频率非常高,因为 New Zealand 是语料库中高频词。如果你采用标准的 unigram 模型,那么显然 Zealand 会比 chopsticks 具有更高的权重,所以最终计算机会选择Zealand这个词(而非chopsticks)填入上面的空格,尽管这个结果看起来相当不合理。这其实就暗示我们应该调整一下策略,最好仅当前一个词是 New 时,我们才给 Zealand 赋一个较高的权值,否则尽管在语料库中 Zealand 也是高频词,但我们并不打算单独使用它。

如果说 P ( w ) P(w) P(w) 衡量了 w w w这个词出现的可能性,那么我们现在想创造一个新的 unigram 模型,叫做 P c o n t i n u a t i o n P_{continuation} Pcontinuation ,它的意思是将 w w w 这个词作为一个新的接续的可能性。注意这其实暗示我们要考虑前面一个词(即历史)的影响。或者说,为了评估 P c o n t i n u a t i o n P_{continuation} Pcontinuation (注意这是一个 unigram 模型),我们其实需要考察使用了 w w w 这个词来生成的不同 bigram 的数量。注意这里说使用了 w w w 这个词来生成的不同类型 bigram 的数量,是指当前词为 w w w ,而前面一个词不同时,就产生了不同的类型。例如:w = “food”, 那么不同的 bigram 类型就可能包括 “chinese food”,“english food”,“japanese food”等。每一个 bigram 类型,当我们第一次遇到时,就视为一个新的接续(novel continuation)。

也就是说 P c o n t i n u a t i o n P_{continuation} Pcontinuation 应该同所有新的接续(novel continuation)构成的集合之势(cardinality)成比例。所以,可知
P c o n t i n u a t i o n ( w i ) ∝ ∣ w i − 1 : C ( w i − 1 w i ) > 0 ∣ P_{continuation}(wi)∝|wi−1:C(wi−1wi)>0| Pcontinuation(wi)wi1:C(wi1wi)>0

如果你对此尚有困惑,我再来解释一下上面这个公式的意思。当前词是 w i wi wi,例如“food”,由此构成的不同类型的 bigram 即为 w i − 1 w i w_{i−1}w_i wi1wi,其中 w i − 1 w i w_{i−1}w_i wi1wi表示前一个词(preceding word)。显然,所有由 w i − 1 w i w_{i−1}w_i wi1wi构成的集合的势,其实就取决于出现在 KaTeX parse error: Expected 'EOF', got '}' at position 4: w_i}̲ 之前的不同的 w i − 1 w_{i−1} wi1 的数量。
然后,为了把上面这个数变成一个概率,我们需要将其除以一个值,这个值就是所有 bigram 类型的数量,即 |{(wj−1,wj):C(wj−1wj)>0}||{(wj−1,wj):C(wj−1wj)>0}|,这里大于0的意思就是“出现过”。于是有
P c o n t i n u a t i o n ( w i ) = ∣ w i − 1 : C ( w i − 1 w i ) > 0 ∣ ∣ ( w j − 1 , w j ) : c ( w j − 1 w j ) > 0 ∣ P_{continuation}(w_i)=\frac{|{wi−1:C(wi−1wi)>0}|}{|{(wj−1,wj):c(wj−1wj)>0}|} Pcontinuation(wi)=(wj1,wj):c(wj1wj)>0wi1:C(wi1wi)>0

当然,我们还可以采用下面这种等价的形式
P c o n t i n u a t i o n ( w i ) = ∣ w i − 1 : C ( w i − 1 w i ) > 0 ∣ ∑ w i ′ ∣ w i − 1 ′ : C ( w i − 1 ′ w i ′ ) > 0 ∣ P_{continuation}(w_i)=\frac{|{w_{i−1}:C(w_{i−1}w_i)>0}|}{∑w^{'}_i|{w^′_{i−1}:C(w^′_{i−1}w^′_i)>0}|} Pcontinuation(wi)=wiwi1:C(wi1wi)>0wi1:C(wi1wi)>0

即所有不同的 bigram 的数量就等于出现在单词 w i ′ w^′_i wi 前面的所有不同的词 w i − 1 ′ w^′_{i−1} wi1 的数量。
如此一来,一个仅出现在 New 后面的高频词 Zealand 只能获得一个较低的接续概率(continuation probability)。由此,再结合前面给出的Absolute Discounting 的概率计算公式,就可以得出插值的 Kneser-Ney Smoothing 的公式,即
P K N ( w i ∣ w i − 1 ) = m a x ( C ( w i − 1 w i ) − d , 0 ) C ( w i − 1 ) + λ ( w i − 1 ) P c o n t i n u a t i o n ( w i ) P_{KN}(w_i|w_{i−1})=\frac{max(C(w_{i−1}w_i)−d,0)}{C(wi−1)} + λ(w_{i−1})P_{continuation}(w_i) PKN(wiwi1)=C(wi1)max(C(wi1wi)d,0)+λ(wi1)Pcontinuation(wi)

其中, m a x ( C ( w i − 1 w i ) − d , 0 ) max(C(w_{i−1}w_i)−d,0) max(C(wi1wi)d,0) 的意思是要保证最后的计数在减去一个 dd 之后不会变成一个负数。其次,我们将原来的 P ( w i ) P(w_i) P(wi) 替换成了 P c o n t i n u a t i o n ( w i ) P_{continuation}(wi) Pcontinuation(wi)。此外, λ λ λ 是一个正则化常量,用于分配之前discount的概率值(也就是从高频词中减去的准备分给那些未出现的低频词的概率值):
λ ( w i − 1 ) = d C ( w i − 1 ) ⋅ ∣ w : C ( w i − 1 , w ) > 0 ∣ λ(w_{i−1})=\frac{d}{C(wi−1)}⋅|{w:C(wi−1,w)>0}| λ(wi1)=C(wi1)dw:C(wi1,w)>0

如果用递归的方式重写出一个更加普适的泛化公式则有:
P K N ( w i ∣ w i − n + 1 ⋯ w i − 1 ) = m a x ( 0 , C K N ( w i − n + 1 ⋯ w i ) − d ) C K N ( w i − n + 1 ⋯ w i − 1 ) + λ ( w i − n + 1 ⋯ w i − 1 ) ⋅ P K N ( w i ∣ w i − n + 2 ⋯ w i − 1 ) P_{KN}(w_i|w_{i−n+1}⋯w_{i−1})=\frac{max(0,CKN(wi−n+1⋯wi)−d)}{C_{KN}(w_{i−n+1}⋯w_{i−1})}+λ(w_{i−n+1}⋯w_{i−1})⋅P_{KN}(w_i|w_{i−n+2}⋯w_{i−1}) PKN(wiwin+1wi1)=CKN(win+1wi1)max(0,CKN(win+1wi)d)+λ(win+1wi1)PKN(wiwin+2wi1)

其中,
λ ( w i − n + 1 ⋯ w i − 1 ) = d C K N ( w i − n + 1 ⋯ w i − 1 ) ⋅ ∣ w : C K N ( w i − n + 1 ⋯ w i − 1 w ) > 0 ∣ λ(w_{i−n+1}⋯w_{i−1})=\frac{d}{C_{KN}(w_{i−n+1}⋯w_{i−1})}⋅|{w:C_{KN}(w_{i−n+1}⋯w_{i−1}w)>0}| λ(win+1wi1)=CKN(win+1wi1)dw:CKN(win+1wi1w)>0

由于采用了上述这种递归的写法,我们需要定义一个计数函数 CKNCKN,它取决于在插值组合中的各阶 N-Gram 处于哪个层级。例如,假设我们现在所使用的插值模型是trigram,bigram 和 unigram 的组合,那么对于最高阶的 trigram 在计数时并不需要使用接续计数(采用普通计数即可),而其他低阶,即 bigram 和 unigram 则需要使用接续计数。这是因为在 unigram 中,我们遇到了一个 Zealand,我们可以参考它的 bigram,同理在 bigram,我还可以再参考它的 trigram,但是如果我们的插值组合中最高阶就是 trigram,那么现在没有 4-gram来给我们做接续计数。用公式表示即为:
C K N ( ⋅ ) = { c o u n t ( ⋅ ) f o r   t h e   h i g h e s t   o r d e r c o n t i n u a t i o n c o u n t ( ⋅ ) , f o r   a l l   o t h e r   l o w e r   o r d e r s C_{KN}(⋅)=\begin{cases}count(⋅) & for\ the\ highest\ order\\ continuationcount(⋅) &, for\ all\ other\ lower\ orders\end{cases} CKN()={count()continuationcount()for the highest order,for all other lower orders
我们前面提到Kneser-Ney Smoothing 是当前一个标准的、广泛采用的、先进的平滑算法。这里我们所说的先进的平滑算法,其实是包含了其他以 Kneser-Ney 为基础改进、衍生而来的算法。其中,效果最好的Kneser-Ney Smoothing 算法是由Chen & Goodman(1998)提出的modified Kneser-Ney Smoothing 算法。很多NLP的开发包和算法库中提供有原始的Kneser-Ney Smoothing(也就是我们前面介绍的),以及modified Kneser-Ney Smoothing 算法的实现。有兴趣的读者可以查阅相关资料以了解更多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值