数学之美读书笔记一(自然语言处理模型)

Jan 22, 2017


从自然语言处理的历史谈起

1956年,包括麦卡锡,香农在内的四个人和另外六位年轻的科学家在达特茅斯学院开了一个头脑风暴式的研讨会,称之为“达特茅斯夏季人工智能研讨会议”。他们讨论了包括人工智能,自然语言处理,神经网络等一系列计算机科学领域未解决的问题。

这是计算机界上一场非常重要的会议,会议的意义甚至超过了10位图灵奖。但他们受到历史的局限,对自然语言处理的理解合在一起甚至都没有超过现今一位一流大学的博士生。全世界都对自然语言处理的研究陷入了误区。

人们对于自然语言处理的理解存在两个阶段,一个是基于规则的句法分析,另一个是基于统计。

从我的观点来看,如果要让我制造一个像如今这样能够处理自然语言的机器,肯定需要给机器加很多的文法规则,比如“我爱你”,这一句话分成主谓宾,然后加上动词名词形容词等等的标签,然后处理成一棵语法树来分析。很明显,既然我都会这样想,早期科学家也会这么想,于是便陷入了一个误区,因为这样来处理自然语言,需要的分析量非常的大,甚至解决不了一句复杂的话,比如下面这句话:

美联储主席伯南克昨天告诉媒体7000亿美元大救助资金将借给上百家银行,保险公司和汽车公司。

就这样的一句话,要用基于规则的方法来分析,显而易见会非常的困难,于是上个世纪七十年代,基于规则的句法分析便已经走到了尽头。这时候陆陆续续有学者提出了新的处理方法,那便是摒弃掉规则,使用基于数学的统计方法。有了分歧,就有了长时间大面积的争论,关于这一场基于规则和基于统计的争论一直持续了15年,一直到上个世纪九十年代初。

为什么会争议了15年这么长时间呢?

早期基于统计的方法并不成熟,上个世纪七十年代,基于统计方法核心是通信系统加隐含马尔可夫模型。1988年,IBM的彼得·布朗等人提出了基于统计大机器翻译方法,虽然框架是对的,但数据量太少GG了,整个八十年代除了他们也没多少人去做了。所以很长的时间里,基于统计的方法只能处理浅层的自然语言处理问题,无法进入深层次的研究。

而20世纪八十年代末之后,计算机的计算能力和数据量大幅度增加,过去看似不能使用的统计方法也变的渐渐有可能了。于是Google等公司还有很多年轻的科学家开始研究这种方法,并且取得了巨大的成果。25年过去了,现在的自然语言处理研究也从单纯的句法分析和语义理解,变成了非常贴近实际应用的机器翻译,语音识别等等等。

基于统计的自然语言处理方法,在数学模型上和通信是相同的,甚至是相同的。因此,在数学意义上自然语言处理又和语言的初衷—通信连接在了一起。

以上历史皆来自于《数学之美》,吴军著。

统计语言模型

为了识别一个句子是否合理,也就是文法合不合适,含义是否正确等,贾里尼克用了一个很简单的统计模型:

一个句子是否合理,那么就看它的可能性大小如何。

这个方法更普遍而严格的描述是:

假定S是一个有意义等句子,由一连串特定顺序排序的词\(w_1\), \(w_2\), \(w_3\)…., \(w_n\)组成,n是句子的长度。现在我们想知道S在文本中出现的概率P(S),我们就可以建立最简单的一个数学模型:

P(S) = P(\(w_1\), \(w_2\), \(w_3\)…., \(w_n\))

展开之后:

\(P(w_1, w_2…., w_n) = P(w_1) * P(w_2|w_1) * P(w_n|w_1, w_2, w_3, w_4.., w_{n-1})\)

从计算上来看,\(P(w_1),P(w_1|w_2)\)都很好算,但后面的几项都越来越难,到最后会变的很复杂。

这时候一个叫马尔可夫的俄国数学家提出了另一种比较有效的方法,因为\(w_i\)出现的概率其实只和前一个词\(w_{i-1}\)的概率有关,于是可以将P(S)变成这样:

\(P(S) = P(w_1) * P(w_2|w_1) … * P(w_n|w_{n-1})\)

这样一来,n项里的每一项都是一个二元条件概率,然后我们就可以将条件概率展开:

\(P(w_i|w_{i-1}) = \frac{P(w_{i-1}, w_i)}{w_{i-1}}\)

上述公式的意思很简单,也就是\(w_{i-1}\)已经出现,\(w_i\)出现的概率是 两个词同时出现的概率/前一个词出现的概率。

于是这样一来,\(P(w_i|w_{i-1})\)要算出来的话只需要统计 两个词在无穷大数据文本中出现的次数/前一个词出现的次数,就可以了。(基于统计中的大数定理)

大数定理: 只要统计量足够,相对频率等于概率。

这样一来,一个句子在文本中出现的概率就可以很方便的解决了,只需要去统计词出现等次数就行了。

高阶语言模型

前一个例子是\(w_i\)出现只和前一个词\(w_{i-1}\)有关,和其他的词都没有关系。

因此,更普遍的假设是\(w_i\)出现和前面的N-1个词都有关系。

\(P(w_i| w_1, w_2, w_3, … w_{i - 1}) = P(w_i| w_{i-N+1}, w-{i-N+2}…w-{i-1})\)

这里可能会有一些难懂,那么就仔细看一下上面的二元模型,我们这个地方只是将二元模型拓展到了N元模型,那么与这个词出现的概率相关的其他词语也从1个变成了N-1个。

实际应用中更多等方法是使用N = 3等三元模型,更高阶的不会使用。

模型的训练,0概率问题,平滑方法

模型训练: 我们通过统计次数来得到概率,基于大数定理,是不会绝对准确等。所以我们要提高准确度,就要对我们的模型进行训练,也就是某些词出现的概率(我们叫做参数)要尽量的接近实际。

模型训练的一个直接的方法就是增加数据量,但是依然会遇到一些问题。

0概率问题: 我们使用的条件概率方法本质是一个除法,而且很容易就陷入分子为0的窘境中,比如”我爱你”这句话在一个超大文本中一直没有出现,那么你能够说出现的概率为0么,显然不是,于是出现了问题。

古德-图灵统计: 对于没有看见的事情,我们不能认为它发现的概率为0.

统计方法改进:假定在语料库中出现r次的词有Nr个,比如未出现的词语数量为\(N_0\),出现一次的词数量为\(N_1\),语料库中所有词语总数为N,很明显(和归一化的思想类似)

\(N = \sum_{r=1}^\infty{r*N_r}\)

那么出现r次的词在语料中的相对频率为:

\(P = \frac{r*N_r}{N}\)

r较小的时候,相对频率会不可靠,因此计算这些词的概率时候,需要一个更小的数字,我们暂且计作\(d_r\), 而不是直接使用r来算。

\(d_r = (r+1)*N_{r+1}/N_r\)

所以,哪怕r = 0, 我们也能给他们赋予一个非零值\(d_r\),解决了0概率问题,并且下调了出现次数少的词语的概率。

所以,当r较小时,出现的概率变为了:

\(P = \frac{d_r}{N}\)

所以,从这里开始,我们要改进我们最开始的二元模型,不再按照原来那种naive的方式计算,我们用更科学的,做一个总结的计算模型:

哎呀。。。这个公式写起来太复杂了,大家可以自己先总结一波,我下一节再直接贴图片上来吧…