语言模型的目的是给句子计算概率。 为什么要计算句子的概率呢?这在多个领域都有作用。比如
在机器翻译领域(machine translation),可以用来区分哪个翻译好,哪个翻译不好,如P(high winds tonite) > P(large winds tonite)
在拼写矫正领域(spell correction),可以用来矫正错误的拼写,如 the office is about fifteen minuets from my house. 由于P(about fifteen minutes)>P(about fifteen minuets),所以这里很可能minuets 拼写错了
在语音识别领域,P(I saw a van ) >> P(eyes awe of an),因此听到类似的读音,前者的可能性更大
如何计算一个句子的概率呢,也就是下述公式
P(W)=P(w1,w2,w3............wn)
计算联合概率P(W)或者计算边缘概率P(wn | w1,w2......wn-1)的模型就是语言模型
如何计算联合概率
P(its water is so transparent that)
这依赖与概率的链式法则
P(A|B) = P(A,B)/P(B)
P(A,B) = P(A|B)P(B)
P(A,B,C) =P(A)P(B|A)P(C|A,B)
P(A,B,C,D) = P(D|A,B,C)P(C|A,B)P(B|A)P(A)
P(x1,x2,x3......xn) = P(x1)P(x2|x1)P(x3|x1,x2)......P(xn|x1,x2,x3......xn-1)
P(its water is so transparent) = P(its)*P(water|its)*P(is|its water)*P(so|its water is)*P(transparent|its water is so)
如何计算概率呢?数数吗?
P(the| its water is so transparent that) = count(its water is so transparent that the) / count(its water is so transparent that)
这样是不可行的!因为英文能组成的句子量是巨大的,我们不能从有限的语料中数数的出来的结果来估计概率
解决的办法:简单假设,一个词只与它前面的那个词有关,即P(the| its water is so transparent that) =P(the|that)
或者,只跟它前面的两个词有关,即P(the| its water is so transparent that) =P(the|transparent that)
也就是条件概率
最简单的模型是一元模型(unigram model),每个词跟前面的0个词有关,则
二元模型(bigram model),每个词跟前面的1个词有关,则
可以扩展成三元,四元,N元模型
但是 这个语言模型有它的不足之处,因为无法解决远距离依赖,比如
the computer which I had just put into the machine room on the fifth floorcrashed
如何计算N-gram模型的参数呢?
最大似然估计
对于二元模型
比如对于语料
I am Sam
Sam I am
I do not like green eggs and ham
那么
P(I|) = c(,I)/c() = 2/3
P(Sam|) = c(,Sam)/c() = 1/3
P(am|I) = c(I,am)/c(I) = 2/3
P(|Sam) = c(Sam,)/c(Sam)=1/2
P(Sam|am)=c(am,Sam)/c(am)=1/2
P(do|I)=c(I,do)/c(I)=1/3
采用berkeley restaurant project sentence作为语料,共有9222个句子,计算二元模型的次数如下表
I | want | to | eat | chinese | food | lunch | spend | |
I | 5 | 827 | 0 | 9 | 0 | 0 | 0 | 2 |
want | 2 | 0 | 608 | 1 | 6 | 6 | 5 | 1 |
to | 2 | 0 | 4 | 686 | 2 | 0 | 6 | 211 |
eat | 0 | 0 | 2 | 0 | 16 | 2 | 42 | 0 |
chinese | 1 | 0 | 0 | 0 | 0 | 82 | 1 | 0 |
food | 15 | 0 | 15 | 0 | 1 | 4 | 0 | 0 |
lunch | 2 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
spend | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
表格里的数据表示词组的个数如第一个格子的5表示 I,I 的次数,827表示I want的个数
每个词的次数如下表
I | want | to | eat | chinese | food | lunch | spend |
2533 | 927 | 2417 | 746 | 158 | 1093 | 341 | 278 |
这样可以计算出 词组的条件概率
I | want | to | eat | chinese | food | lunch | spend | |
I | 0.001974 | 0.32649 | 0 | 0.003553 | 0 | 0 | 0 | 0.00079 |
want | 0.002157 | 0 | 0.655879 | 0.001079 | 0.006472 | 0.006472 | 0.005394 | 0.001079 |
to | 0.000827 | 0 | 0.001655 | 0.283823 | 0.000827 | 0 | 0.002482 | 0.087298 |
eat | 0 | 0 | 0.002681 | 0 | 0.021448 | 0.002681 | 0.0563 | 0 |
chinese | 0.006329 | 0 | 0 | 0 | 0 | 0.518987 | 0.006329 | 0 |
food | 0.013724 | 0 | 0.013724 | 0 | 0.000915 | 0.00366 | 0 | 0 |
lunch | 0.005865 | 0 | 0 | 0 | 0 | 0.002933 | 0 | 0 |
spend | 0.003597 | 0 | 0.003597 | 0 | 0 | 0 | 0 | 0 |
实际操作中在计算一个句子的概率时,会采用对数,因为p1*p2*p3....*pn会导致乘出来的数特别小,而且加法也比乘法更容易计算
log(p1*p2*p3*p4) = logp1+logp2+logp3+logp4
一些语言模型的工具箱
SRILM
http://www.speech.sri.com/projects/srilm
google N-gram
http://googleresearch.blogspot.com/2006/08/all-our-n-gram-are-belong-to-you.html
google book n-gram
http://ngrams.googlelab.com
如何评价一个语言模型的好坏呢?
模型是否能识别出更好的句子,好的句子概率比坏的句子的概率更大
比较模型A和B好坏的最好检测是,将A和B应用于一个任务,比如拼写检查,语音识别,机器翻译等,得到A和B的精度,有多少错写的字母被正确检测到了,有多少单词被正确的翻译了。这被称为Extrinsic evaluation。
Extrinsic evaluation非常耗时。
intrinsic evaluation是只评价模型本身,而不需要用到外部的任务
intrinsic evaluation就是来评价perplexity(混乱)
举个例子,如何预测下一个单词
I always order pizza with cheese and ?
下一个词可选择的有
mushrooms 0.1
pepperoni 0.1
anchovies 0.01
fried rice 0.0001
and 1e-100
一个好的模型 就是给真实出现的下一个单词赋予最大的概率
一个好的模型就是能最好的预测测试集
Perplexity定义:测试集的概率,用词数开方
perplexity 就是average branch factor
如果对于下一个词有10个等概率的词作为选择,则perplexity就是10
lower perplexity = better model
遇到0的情况如何处理?
也就是在训练集里面没有遇到这个词组,但是在测试集里面遇到了,怎么计算呢?肯定不能把此时算成0,否则句子的概率就是0了,也没法计算perplexity了
最简单的想法就是加一平滑add one smoothing,也叫laplace smoothing 我们将训练集里面出现过的词组的概率抽出一点平摊到没有出现过的词组上
其中V是单词的个数,unigram的单词个数
还是用berkeley restaurant project sentence作为语料的例子,采用加一平滑之后,词组的次数如下
I | want | to | eat | chinese | food | lunch | spend | |
I | 6 | 828 | 1 | 10 | 1 | 1 | 1 | 3 |
want | 3 | 1 | 609 | 2 | 7 | 7 | 6 | 2 |
to | 3 | 1 | 5 | 687 | 3 | 1 | 7 | 212 |
eat | 1 | 1 | 3 | 1 | 17 | 3 | 43 | 1 |
chinese | 2 | 1 | 1 | 1 | 1 | 83 | 2 | 1 |
food | 16 | 1 | 16 | 1 | 2 | 5 | 1 | 1 |
lunch | 3 | 1 | 1 | 1 | 1 | 2 | 1 | 1 |
spend | 2 | 1 | 2 | 1 | 1 | 1 | 1 | 1 |
采用加一平滑计算概率
V=1449
I | want | to | eat | chinese | food | lunch | spend | |
I | 0.001507 | 0.207936 | 0.000251 | 0.002511 | 0.000251 | 0.000251 | 0.000251 | 0.000753 |
want | 0.001263 | 0.000421 | 0.256313 | 0.000842 | 0.002946 | 0.002946 | 0.002525 | 0.000842 |
to | 0.000776 | 0.000259 | 0.001293 | 0.177703 | 0.000776 | 0.000259 | 0.001811 | 0.054837 |
eat | 0.000456 | 0.000456 | 0.001367 | 0.000456 | 0.007745 | 0.001367 | 0.01959 | 0.000456 |
chinese | 0.001245 | 0.000622 | 0.000622 | 0.000622 | 0.000622 | 0.051649 | 0.001245 | 0.000622 |
food | 0.006294 | 0.000393 | 0.006294 | 0.000393 | 0.000787 | 0.001967 | 0.000393 | 0.000393 |
lunch | 0.001676 | 0.000559 | 0.000559 | 0.000559 | 0.000559 | 0.001117 | 0.000559 | 0.000559 |
spend | 0.001158 | 0.000579 | 0.001158 | 0.000579 | 0.000579 | 0.000579 | 0.000579 | 0.000579 |
我们可以用这个概率来推算出词组的个数,就好像词组本来是这样的次数,才计算出这个概率的
I | want | to | eat | chinese | food | lunch | spend | |
I | 3.816675 | 526.7012 | 0.636113 | 6.361125 | 0.636113 | 0.636113 | 0.636113 | 1.908338 |
want | 1.170455 | 0.390152 | 237.6023 | 0.780303 | 2.731061 | 2.731061 | 2.340909 | 0.780303 |
to | 1.875582 | 0.625194 | 3.12597 | 429.5083 | 1.875582 | 0.625194 | 4.376358 | 132.5411 |
eat | 0.339863 | 0.339863 | 1.01959 | 0.339863 | 5.777677 | 1.01959 | 14.61412 | 0.339863 |
chinese | 0.19664 | 0.09832 | 0.09832 | 0.09832 | 0.09832 | 8.160548 | 0.19664 | 0.09832 |
food | 6.879622 | 0.429976 | 6.879622 | 0.429976 | 0.859953 | 2.149882 | 0.429976 | 0.429976 |
lunch | 0.571508 | 0.190503 | 0.190503 | 0.190503 | 0.190503 | 0.381006 | 0.190503 | 0.190503 |
spend | 0.321946 | 0.160973 | 0.321946 | 0.160973 | 0.160973 | 0.160973 | 0.160973 | 0.160973 |
通过这个数据能看出 add-1 smoothing将原本的词组个数改变了多少
可以看出,add-1平滑对原数据的影响非常大,因此对N-gram来说它并不是一个很好的模型。实际中,n-gram也不用add-1 smoothing。 它用于其它的NLP领域,如文本分类,或者0值不是 很多的情况
备注:
加一平滑时,需要事先知道V是多少,也就是总的词的种类数。对于二元语法来说,尽管语料中不是每个词都出现在wi-1之后,但是平滑的时候把未出现过的也加了1,也就相当于V个词都在wi-1后出现过了。对于一元语法来说,就算不是每个词都出现过,平滑的时候把未出现过的加一,这就需要事先知道到底有哪些种类,而不能只从出现过的词里面统计V
多个语言模型内插
如果有足够的数据,trigram会比bigram效果更好,但是,有时候 没有足够的观测数据来支撑trigram时,会转而用bigram,如果还是没有足够的数据支撑,会转而用unigram。这叫做backoff.
我们可以将trigram,bigram,unigram结合起来,这样能有更好的效果。
简单内插
有上下文的内插
lambdas从何而来呢?
常用的方法是使用一个held-out data
准备三个数据集,training data,held-out data, test data
先从training data里面训练处lambdas,然后看那个lambdas能使held-out data出现的概率最大
对于海量的n-gram数据,如何做平滑?
stupid backoff
关于平滑
加一平滑
更一般的,可以变为 加k平滑
将上述公司做一个简单的变化,引入一个参数m=kV
上述公式相当于在二元模型的基础上加上了一个与词典个数相关的常量。
我们还可以将这个常量改成跟一元模型有关的
这也相当于是一种内插
另外一种平滑方法good turning smoothing
使用我们只看到过一次的事件来估算从没看到过的事件
用Nc表示出现过c次的单词数
如句子 Sam I am I am Sam I do not eat
N1 = 3
N2 = 2
N3 = 1
假设你在钓鱼 ,你钓到了
10 carp, 3 perch,2 whitefish,1 throut, 1 salmon, 1 eel 共18只
那么下一只有多大的可能性是throut?
1/18
如果再问,下一只是新品种的鱼的可能性是多少?
肯定不能说是0,0就完全没有可能了,这是不现实的。
good turning smoothing用只看到过一次的事件来估计从没看到过的事件
因此下一只是新品种鱼的可能性是3/18,因为N1=3
假设是这样,那么下一只是throut的可能性还有多大呢?
肯定是小于1/18的
如何估算?
因此,对于没有看到的鱼,用最大似然法的话,下一次出现 的概率是0,而用good turning smoothing,下一次出现的概率是3/18
对于throut,用最大似然法的话,下一次出现 的概率是1/18,而用good turning smoothing,c = 2*N2/N1 = 2/3,下一次出现的概率是2/3/18 = 1/27
为什么可以这么计算次数?
待写
另一种平滑kneyser-ney smoothing