5.1_.jpg

 今天要讲的内容简单说就是预测单词,例如有一个句子,“please turn yourhomework”,如果我们要预测这个句子接下来最先出现的单词是什么的话,凭经验很有可能是单词“in”,当然也有可能是“over”。我们之所以有这样的直觉,是因为根据我们自身经验,出现“in”和“over”的概率比较大。

 
在语音识别中,如果周围噪声比较大,很难听清楚每一个单词,这时候凭借概率就可以令识别的准确度进一步提高;同样,在手写字识别里,我们也可以根据前面的输入历史来猜测下一个输入的字是什么;同样,在机器翻译里,对于句子语法的通顺和连贯也需要概率去辅助。


单词组成序列,对序列出现的概率做出推测就是语言模型的作用,而语言模型中最简单的是N-gram,一个N-gram是指对由N个单词组成的序列出现的概率进行计算,例如2-gram(或bigram)是对由两个单词组成的短语出现的概率进行判断,像“please turn”、“turn your”、“your homework”等等;3-gram是对由三个单词组成的短语出现的概率进行判断,像“please turn your”、“turn your homework”等等。

 
N-gram模型可以用来预测下一个单词,也可以用来判断一整句出现的概率。无论是预测单词还是求整句出现的概率,N-gram都是语音识别和自然语言处理中的重要模型。

 
首先让我们认真分析一下开头提到的例子,如果我们要计算P(w|h),即给定历史句子,求出下一个单词出现的概率。假设历史句子是“please turn your homework”,我们想知道下一个单词为“in”的概率,用公式表示如下:

P(in|please turn your homework)

 
一种方法是运用出现的相对频次来计算,我们可以去寻找一个非常大的语料库,从中去统计序列“pleaseturn your homework”出现的总次数,同时也统计序列“please turn yourhomework in”出现的总次数,这样我们把两者次数相除,就可以用频率去代替概率计算了,公式如下:

P(in|please turn your homework)=C(pleaseturn your homework in)/C(please turn your homework)

 
虽然这种方法在一般情况下行之有效,但是由于语言是动态发展的,就算拥有万维网那么大的语料库,也有可能会遇到之前没有统计的新句子。首先,我们来看看一整个句子出现的概率怎么求,假设一个句子是由单词W1,W2,…,Wn组成的,那么一整个句子出现的概率就是这些单词出现的联合概率P(W1W2…Wn),我们可以使用概率的链式法则来分解计算这个联合概率:

P(W1W2…Wn)=P(W1)*P(W2|W1)*P(W3|W2W1)*…*P(Wn|Wn-1…W2W1)


上面这个链式法则告诉我们计算一个联合概率等于计算多个条件概率的乘积,也就是说计算一个句子出现的概率等于计算多个给定历史序列计算单词出现概率的乘积。但是,链式法则似乎并不能帮助我们解决问题,因为我们暂时还不能对给定历史序列计算单词出现的概率,即P(Wn|Wn-1…W2W1)我们无法求出,而且我们也不能按照统计序列出现的次数来求,因为语言是动态发展的,很有可能一个新句子是以前从没出现过的。

 
N-gram的巧妙之处就在于,我们既然无法求出给定历史下一个单词出现的概率,但是我们可以根据历史的最后一小节来计算一个单词出现的概率,这是一种近似的手段,这种近似又称为马尔科夫假设,即下一个单词出现的概率仅仅与前几个单词有关。

 
首先,最简单的近似是bigram模型,下一个单词出现的概率仅仅与上一个单词有关,也就是说P(Wn|Wn-1…W2W1)=P(Wn|Wn-1),回到我们之前的例子,要计算P(the|pleaseturn your homework)实际上就是计算P(in|homework)了。

 
同样的道理,如果是trigram的话,下一个单词出现的概率仅仅与上两个单词有关,也就是说P(Wn|Wn-1…W2W1)=P(Wn|Wn-1Wn-2),回到我们之前的例子,要计算P(in|pleaseturn your homework)实际上就是计算P(in|your homework)了。对于一般的情况N-gram,也就是说下一个单词出现的概率仅仅与上N-1个单词有关。

 
那么我们怎么计算bigram中的概率呢?同样,我们可以使用最大似然估计法,通过统计一个语料库中的homework *和homework in的次数,然后相除即可,用公式表示如下:

P(in|please turn your homework)=P(in|homework)=C(homeworkin)/SUM[C(homework *)]



其中SUM[C(homework *)]就是统计所有以homework开头的两个单词出现的次数,因为C(homework *)=C(homework),也就是说我们只用统计homework出现的所有次数即可,于是,上面的同时简化为:

P(in|please turn your homework)=P(in|homework)=C(homeworkin)/C(homework)


下面看一个具体的例子,该例子中有三个句子,而我们在每个句子的开头和末尾添加了起始符<s>和终止符</s>:



<s> I am Sam </s>

<s> Sam I am </s>

<s> I do not like green eggs and ham</s>



下面来计算从这个语料库中得出的部分bigram概率:

P(I|<s>)=2/3

P(Sam|<s>)=1/3

P(am|I)=2/3

P(do|I)=1/3

P(</s>|Sam)=1/2

P(Sam|am)=1/2

于是,P(I am Sam)=P(I|<s>)* P(am|I)* P(Sam|am)*P(</s>|Sam)=2/3*2/3*1/2*1/2=1/9

 

实际中,bigram和trigram或许不能较好地解决问题,那么4-gram、5-gram都是有可能用上的;同时,由于多个概率相乘会导致数值越来越小,为了避免这种数值不稳定,可以使用对数相加来代替概率相乘,然后取e指数即可还原。
 
 
 
 
 
来源:张泽旺 深度学习每日摘要
智造家