本章介绍语言模型,包括如下内容:
- Introduction to N-grams
- Estimating N-gram Probabilities
- Evaluation and Perplexity
- Generalization and Zeros
- Smoothing: Add-One
- Interpolation
- Good-Turing Smoothing
- Kneser-Ney Smoothing
- 1. Introduction to N-grams
- 我们现在使用是Probalilistic Language Models(概率语言模型)。即估计一个字符串序列或者句子出现的可能性大小。
- 比如说W是一句话,w1,w2,...,wn是构成这句话的单词,W = w1,w2,...,wn
- P(W)指代这句话的出现的概率
- P(W) = P(w1,w2,...,wn) ——公式1.1
- 而
- P(w1,w2,...,wn) = P(w1)*P(w2|w1)*P(w3|w1,w2)*...*P(wn|w1,w2,...,wn) ——公式1.2
- 就像计算如下一句话的概率:
-
-
其计算公式的一般表示法为:
- 即我们需要知道每个wi(i=1...n) 在w1,w2,...wi-1条件下的概率P(wi|w1,w2,...wi-1),要计算每个单词在前面几个单词出现的条件下的概率是很难的,因此我们采用简化的方法,我们认为每个单词的出现只与它的前一个单词相关即P(wi|w1,w2,...,wi-1) ≈ P(wi|wi-1),这样就比较容易计算了,这样的模型成为”二元“模型。
- 当然我们也可以有个更通用的定义:每个单词都只与它前面的N-1个单词相关,那么P(wi|w1,w2,...,wi-1) ≈ P(wi|wi-N+1, wi-N+2,...,wi-1),那么该模型就成为”N元模型“
- 最简单的模型即Unigram model(一元模型),即认为每个单词出现的概率只与本身相关,不受之前单词的影响,那么
-
- 我们也可以使用4元模型、5元模型,N越大,语言模型的准确率就越大,但是每增加一元,带来的是计算量的指数增长,而且有的时候就算是5阶,也不可能把单词与前面单词的关系展示清楚,如下面一句话的最后一个单词crashed,实际上是与句子中靠前的computer相关,这种情况称为”长程依赖“,就算是使用5元模型也不可能把单词之前的相关性展示出来。
-
-
-
- 补充:
- 条件概率的公式:
- P(A|B) = P(A,B) / P(B) ——公式1.3
- (公式1.3)转换成
- P(A|B) * P(B) = P(A,B) ——公式1.4
- 注意:
- 本章内容建议提前看一下吴军老师所著的《数学之美》第三章——统计语言模型。
-
2. Estimating N-gram Probabilities(估算模型参数)
上节我们讲了N元语言模型,下面我们学习一下该如何求N元模型的概率。
每对单词的条件概率称为该语言模型的“模型参数”,求取参数的过程称之为“模型训练”。
以”二元“模型为例,我们需要知道句子W中每个单词wi出现在wi-1之后的概率P(wi|wi-1)
公式如下:
即我们只需要用全部语料库中出现连着出现(wi-1,wi)的次数 除以 wi-1出现的次数,当然我们要保证语料库足够大。
下面是对一个比较大的语料库(貌似是与餐馆相关的)进行统计的结果:
上一栏是:(列单词,行单词)出现的次数,如(i, want)出现的次数是827
中间一栏是:"I want to eat chinese food lunch spend"8个单词统计总数;
最下一栏是:每对单词出现次数/总数 求得的概率,如(i,want)/2533 = 0.33
计算完每相邻两个单词出现的概率后,就可以得到这句话出现的概率
P(w1,w2,...,wn) = P(w1) * P(w2|w1) * P(w3 | w2) * ... * P(wn |wn-1)
实际上从每对单词出现的概率上我们也能总结出一些知识。比如说下面的图中所显示的,(want, english)出现的概率比(want, chinese)低,大概是因为中国食品更受欢迎一些。(want, to)和(to, eat)是固定的语法规则,而(spend, want)不和语法,因此出现的概率为0.
补充:
在实际的运算中,往往把公式
P(w1,w2,...,wn)= P(w1) * P(w2|w1) * P(w3 | w2) * ... * P(wn |wn-1)
写成log( P(w1,w2,...,wn) ) = log( P(w1)) + log( P(w2|w1)) + ... + log( P(wn|wn-1))的形式
这样既可以避免underflow(下溢,具体不知道什么意思),而且做加法比做乘法快。
有一些公开的语言模型工具,如:
1. SRILM
点击打开链接
2. Google N-Gram Release
Google Machiine Translation Team公开的大数据集,你可以自己下载
3. Google Book N-grams
点击打开链接
3. Evaluation and Perplexity
本节我们将评估之前所建立的语言模型(是否比其它模型更准确)。
首先我们根据training set(训练集数据)求得模型参数,然后使用新的数据集(test set)来测试所建立语言模型的性能。
Train set和Test set属于同一领域时,训练出的语言模型的准确性就高,对test set的预测性就越好。倘若两者属于不同领域,那么所训练的模型就未必好。
Extrinsic(外部)evaluation:根据一个具体的任务,训练两个语言模型A和B,然后使用大量数据来监测A和B,比较两者的错误率等等。这回消耗大量时间,需要几天到几周不等。
Intrinsic (内部)evaluation: Perplexity(混乱度)的定义如下。
PP(W)y越小就意味着P(W)的可能行越大。对与普适模型和二元模型PP(W)的公式如下
PP(W)越小,语言模型的性能也就越好
4. Generalization and Zeros
在二元语言模型中,很多单词对出现的次数为0,实际上在|V^2种单词对中,大多数的单词对出现的次数都是0,在多元模型中情况更甚,会有更多的概率为0的单词对(语料库的词汇量为|V|,N元模型中单词序列种类为|V|的N次方)。
另一个问题是:很可能我们使用的train set数据中计算的某个单词对概率为0,但是在test set中确实真实存在的。
如下面这个例子:
5. Smoothing: Add-One
解决零概率的方法称为为平滑技术。
在我们的train set中统计到denied the的搭配有3个allegations,2个reports,1个claims和1个request,总共7个。但这个模型中并没有denied the attack,denied the man等等用法,而这些搭配在test set中很可能会出现,因此smoothing的方法就是从概率总和中偷出一部分用来代表那些未出现的搭配的概率,而原有的搭配的概率相应地减小。如下图所示:2.5个allegations,1.5个reports,0.5claims,0.5个request,再加上2个其它可能的搭配,总共还是7个。
按照什么样的方法“偷”一部分概率给那些未出现的可能性呢?最简单的方法成为Add-one estimation,亦称Laplace smoothing(拉普拉斯平滑)。这个方法的核心很简单:我们假定每个单词至少都出现一次,对所有的单词,其出现的个数都+1,即使在train set中并没有出现也是如此操作。因此我们之前计算模型参数的公式就由
变成
注:
MLE代表最大似然估计,是从train set中得到的原始概率。给定一个语料库,通过原始(简单求概率未经修改的)方法训练出来的模型,我们称之为maximum-likelihood语言模型。
V即train set语料库的
词汇量(出现“零概率“时有两种可能,一种是在train set中的确没有(wi-1,wi)搭配,还有一种是train set中压根没有test set中的某些单词。因为我们只能根据train set求参数,test set是未知的,因此,这里的V只能是train set的词汇量,我们把语料库中的每种单词的默认数量都+1,相应的认为wi-1可以与语料库中所有的单词都存在一次以上的搭配可能性)
还是使用之前的restaurant语料库,对其进行laplace smoothed
然后再计算概率
将通过laplace smooth计算的概率再乘以总数得到平滑后不同单词搭配出现的次数,与之前原始数据次数相比较。
你可以发现两者之间差别很大,比如(chinese, food)从82变成了8.2,因为更多的概率分配给了那些在train set 中没有出现但可能的搭配。
正因如此,add-1 estimation并非”锋利“的工具,它不适用于N-grams,我们在之后会讲到更好的 方法。Add-1 通常用于平滑其它一些NLP模型,如text classification(文本分类),以及一些零概率出现比较少的情况。
6. Interpolation (插值)
有时我们需要将多种语言模型——trigram(三元)、bigram(二元)、unigram(一元)模型混合使用,这就需要使用插值方法。
简单插值,给unigram/bigram/trigram的概率赋一个权值,权值之和为1,如下图所示:
另一种就是λ取值由上下文决定,如下图所示:
如何设置λ呢?这里我们介绍一个新的概念”held-out data"(留存数据或留存语料)。把原有的train set数据分成两份,一份继续作为train set(训练语料),用于初始的频率估计;另一份用来改善最初的频率高几,这一份便称为“held-out data"。设置λ的方法如下图所示:
即我们选择的λ要使得修改后的语言模型能够最佳匹配到held-out data。
假如事先知道所有的单词,即V是固定的,那么就训练语言模型的过程就称为closed vocabulary task;假如不知道所有的单词,即test set中的某些单词并没有在train set中出现,那么这些单词就称为OOV(out of vocabulary) words,并为这些单词指定一个统一个标识符,相应的训练语言模型的过程称为open vocabulary task.
7. Good-Turing Smoothing(古德-图灵平滑)
第6节中我们讲到的Add-One平滑,其更一般的形式是Add-k平滑(就是把原来的加1换成加常数K),公式如下:
此外,还有其他更高级的平滑方法,如Good-Turing/Kneser-Ney/Witten-Bell等。
我们先介绍一个基本定义:Nc——出现c次的单词的种类的个数。
如:Sam I am I am Sam I do not eat 统计如下:
I 3
sam 2
am 2
do 1
not 1
eat 1
因此N1=3,N2=2,N3=1.
Good-Turning的计算方法如下:
先看前一个公式:前一个公式是得到我们所没看到的事件的概率,这些事件在训练数据中没有,但在现实生活中很可能存在。方法是用N1(即只出现1次的事件数)除以事件总数。
再看第二个公式:因为前面已经把一部分概率分给了未出现的事件,那么之前已经出现的事件的概率也需要相应的减少,这个公式就是计算之前出现的事件的概率,C*代表的是Good-Turning count。
举例说明,我钓了18条鱼,分别是
10carp,3 perch,2 whitefish,1 trout,1 salmon,1 eel = 18 fish
N1=3,N2=1,N3=1,N10=1
问题一:我钓的下一条鱼是trout的概率是?采用MLE最大似然估计的方法答案是1/18
问题二:下一条鱼是新的品种的概率是?假如采用MLE最大似然估计的方法,那么答案是0/18;而采用Good-Turing估计,则为N1/N=3/18.
问题三:下一条鱼是trout的概率是?Pmle(trout)=1/18;而使用Good-Turing方法,新种鱼的概率已经占去了3/18,因此Pgt(trout)肯定小于Pmle(trout)。计算可得:C*(trout)=2·N2/N1=2/3,Pgt(trout)=C*(trout)/18=1/27.
细心的读者会注意到,出现次数最多的单词经过Good-Turing计算的C*等于零,因为N(c+1)=0,这显然是与常识违背的,因为出现最多的单词,下一次出现的概率也应该最大才是。另外,倘若单词计数有断层,就像下图所示,也会出现C*=0的情况。
如上图所示,当词频k比较小时,N(k)远大于N(k+1),因此计算出的C*可以比C小,进而使得Pgt比Pmle小。
而当k比较大时,情况就不一定了,C*的值可能比C大,也可能比C小,很可能在C周围浮动,另外,断层现象会增加,显而易见,当语料库比较大时,出现1,2,3,...几百次的都会有,但是当k增长到几千的时候,N(k)就不一定存在了。
解决方法是对N(k)进行平滑处理,处理成下图的样子:
1.8
Kneser-Ney Smoothing
本节介绍Kneser-Ney平滑方法。