考虑一个语音识别系统,假设用户说了这么一句话:“I have a gun”,因为发音的相似,该语音识别系统发现如下几句话都是可能的候选:1、I have a gun. 2、I have a gull. 3、I have a gub. 那么问题来了,到底哪一个是正确答案呢?
一般的解决方法是采用统计的方法。即比较上面的1、2和3这三句话哪一句在英语中出现的概率最高,哪句概率最高就把哪句返回给用户。那么如何计算一个句子出现的概率呢?说白了就是“数数”的方法。但是即使是“数数”也有很多种数法,其中,最简单的策略如下:
给定一个语料库,数出其中所有的长度为4的句子的个数,设为N,然后再看在这N个长度为4的句子中,“I have a gun”出现了多少次,不妨设为N,那么句子“I have a gun”的概率就是N/N。其它两个句子的概率也这么计算。
上述的这种数数方法,从逻辑上讲是完全OK的,但是因为自然语言的灵活多变性,以及语料库的规模总是有限的,对于一个稍长一点的句子,很可能语料库中根本就没有。比如说下面这个句子:“I am looking for a restaurant to eat breakfast”,直观上看,这句话在语料库中应该出现次数很多吧?但是如果把这句话输入到Google的搜索框中,点击搜索,你会发现返回的结果中根本就没有完全匹配上的。所以,我们需要提出更加有效的“数数”方法。
为了把事情说清楚,需要引入一些简单的数学符号。
1、word序列:w, w, w, … , w
2、链式规则:P(w, w, w, … , w)=P(w)P(w|w)P(w|ww)P(w|www)…P(w|ww…w)
好了,我们想要计算“I have a gun”的概率,也就是计算P(I,have,a,gun),按照链式规则,则有:
P(I,have,a,gun)=P(I)P(have|I)P(a|I,have)P(gun|I,have,a)
但是事情并没有得到简化,例如要计算P(gun|I,have,a),按照条件概率公式展开:
P(gun|I,have,a) = P(I,have,a,gun)/P(I,have,a)
发现了什么?为了计算P(gun|I,have,a),我们需要先计算P(I,have,a,gun)和P(I,have,a)。哎?P(I,have,a,gun)不就是我们一开始想要计算的值吗?所以绕了一圈,我们又回到了原地?
好了,现在我们来整理一下思路。
对于一个句子,其可以表示为一个word序列:w, w, w, … , w。我们现在想要计算句子出现的概率,也就是计算P(w, w, w, … , w)。这个概率我们可以直接用数数的方法求解,但是效果并不好,所以我们利用链式规则,把计算P(w, w, w, … , w)转化为计算一系列的乘积:P(w)P(w|w)P(w|ww)P(w|www)…P(w|ww…w)。但是转化之后,问题并没有变得简单。怎么办?
N-gram这时候就派上用场了。
对于1-gram,其假设是P(w|ww…w)≈P(w|w)
对于2-gram,其假设是P(w|ww…w)≈P(w|w,w)
对于3-gram,其假设是P(w|ww…w)≈P(w|w,w,w)
依次类推。
所以:
在1-gram模型下:
P(w, w, w, … , w)=P(w)P(w|w)P(w|ww)P(w|www)…P(w|ww…w)
≈P(w)P(w|w)P(w|w)P(w|w)…P(w|w)
在2-gram模型下:
P(w, w, w, … , w)=P(w)P(w|w)P(w|ww)P(w|www)…P(w|ww…w)
≈P(w)P(w|w)P(w|ww)P(w|ww)…P(w|ww)
在3-gram模型下:
P(w, w, w, … , w)=P(w)P(w|w)P(w|ww)P(w|www)…P(w|ww…w)
≈P(w)P(w|w)P(w|ww)P(w|www)…P(w|www)
假设我们采用的是1-gram模型,那么:
P(I,have,a,gun)=P(I)P(have|I)P(a|have)P(gun|a).
然后,我们再用“数数”的方法求P(I)和其他的三个条件概率:
P(I)=语料库中I出现的次数 / 语料库中的总词数
P(have|I) = 语料库中I和have一起出现的次数 / 语料库中I出现的次数。
总结,本文只是对N-gram做了非常简单的介绍,目的在于简单易懂,但是不够严谨。感兴趣的同学可以进一步查阅相关的资料。在任何一本关于自然语言处理的书上都能够找到N-gram的内容。