NLP中的语言模型


        语言模型是自然语言处理领域非常重要的模型,简单来讲,就是用来计算句子概率的模型。那么句子概率又是怎么算的呢?我们知道词构成句。在自然语言处理中,通常以词作为基本单位,把句子称为由词按照一定的规则组成的词的序列。不妨设一个句子为:

                    

nlp语言模式 nlp的模型_nlp语言模式

这样,这个句子便是由n个词组成的词序列。那么这个句子的概率,可以表示如下:

    

nlp语言模式 nlp的模型_nlp语言模式_02

这就是n-gram model的表示式,把这每个概率也叫做模型参数,所谓的n-gram model指的是每个词依赖于之前的n-1个词。

但是,有两个问题:①参数过多:条件概率太多,假设每个概率都存在(假设语料库能够满足表示式),这会导致很大的计算开销,而且占用的存储量很大,因为模型训练的目的,就是求解模型参数,保存这些参数值,就很占内存了。

②数据稀疏严重:在实际中,尽管语料库很大,但是也有可能,会出现某些条件概率为0的情况,这很明显,一篇文章不可能包含一部分词的所有组合。根据最大似然估计,一个值概率为0,导致整个概率为0,这显然不科学,这就跟朴素贝叶斯,不经过平滑处理一样。

对于上面两个问题,自然有解决他们的方法。

        首先对于第一个问题,即参数空间过大的问题,引入了马尔可夫假设:任意一个词出现的概率只与它前面出现的有限的一个或者几个词有关。如果一个词的出现与它周围的词是无关的,换言之,独立于它周围的词,那么把这样的语言模型称之为“上下文无关模型”,又称为unigram model,或者一元语言模型,即:

    

nlp语言模式 nlp的模型_nlp语言模式_03

再如,如果一个词的出现仅仅依赖于它前面出现的一个词,把这样的语言模型称之为bigram model,二元语言模型,即:

                                              

nlp语言模式 nlp的模型_机器学习_04

再举一例,如果一个词的出现仅依赖于它前面出现的两个词,那么把这样的语言模型称之为Trigram model,即三元语言模型,即:

                                         

nlp语言模式 nlp的模型_语言模型_05

所以,正如刚开始说的,一般来说,N元语言模型就是假设当前词的出现的概率只与它前面出现的N-1个单词有关。而这些概率参数都是可以通过大规模语料库来计算得到的,举个例子,对于三元语言模型来说:

                                                   

nlp语言模式 nlp的模型_机器学习_06

在实际应用中,用得最多的就是二元语言模型和三元语言模型了,当然这取决于语料库的规模,理论上,N越大,效果越好,表示越准。之所以高阶的语言模型用的少,还是因为数据规模有限,即语料库规模有限,而且,在有限的语料库下,强行使用高阶模型,会出现数据稀疏问题,时间复杂度高,精度的提升并不明显。下面对于上面提到的语言模型举例,讲解清楚。

        一元语言模型(unigram model)

        在一元语言模型中,一句话s的概率为:

                                                       

nlp语言模式 nlp的模型_语言模型_07

在这里,这个式子成立的条件是有一个假设,就是条件无关假设,每个词都是条件无关的。那么上面的公式如何计算呢?首先说明一点,这里的参数种类是一种,即全部是每个词单独的概率的乘积,但是参数实例,即我们的词的个数有V个(V是我们建立的词典的大小,即语料库中,所有的不同词的个数),但是如何得到每个参数实例的值呢,即每个参数对应的词的个数。这里用的是极大似然估计法。比如说我们有下面这个语料:

                        我的研究领域是机器学习和自然语言处理,自然语言处理和机器学习很有趣。

好的,字典的定义,没有重复字构成的索引字段,这里有34个字符,包括标点符号","和"。" 但是"自然语言处理和机器学习"有重复,所以去掉后,我们的字典为:”我的研究领域是机器学习和自然语言处理,很有趣。“这样字典便有23个字符,也就是说我们的字典长度是23,每个字词的概率可以直接用最大似然法估计得到。比如P(我)=1/34,注意:这里的分母为源语料的大小,而不是字典的大小。对于一元语言模型,一个字,一个字的算,再比如P(学)=2/34,这样,我们就需要存储我们学习到的模型参数,参数向量的长度是22,因为每个字算个概率,字典长度为22,因此参数向量的长度为22。每个维度保存着每个字的概率值。那么对于其中一句话,如何估计它的概率呢?比如”机器学习和自然语言处理"这句话。

        好的,根据一元语言模型的特点,这样算:

   P(机器学习与自然语言处理)=P(机)*P(器)*P(学)*P(习)*P(自)*...*P(理)=(2/34)*(2/34)*...*(2/34)便可算出结果,实质上就是将待计算的句子拆解为单个的字,然后,把这些字的概率乘起来,就是结果。这非常的粗暴,完全没有考虑到字词的上下关系,用朴素贝叶斯模型的话来说too naive。再来看看二元语言模型是如何做的。

        二元语言模型

        二元语言模型在之前已经介绍过了,每个词依赖于它前面出现的1个词的情况。简单点,考虑下面两句话:

                            ①他打我                                                       ②我打他

来看看用一元语言模型来计算的情况:

                    P(他打我)=P(他)*P(打)*P(我)              p(我打他)=P(我)*P(打)*P(他)

可以看到,这两句话的概率是一样大的,但是如果一篇文章主要是描述他打我的,那么显然P(他打我)应该要高于P(我打他),这没错吧。这就是一元语言模型带来的缺陷,因为每个字词都是条件无关的,这样导致的结果就是我们考虑不到字词之间的连接关系。因此在整篇语料中,应该考虑P(我|打)和P(他|打)的大小关系。这便是二元语言模型所要解决的事情。

在使用二元语言模型之前,字典的建立与一元语言模型字典的建立是一样的,也就是说字典的建立跟语言模型的使用没有关系。这里采用的做法是给句子加个“始”和“终”标志,表示要计算的句子的开始与结束。

比如P(他打我)=P(他|始)*P(打|他)*P(我|打)*P(终|我)

对于二元语言模型结合大数定律可得到任意一个参数计算公式为:

nlp语言模式 nlp的模型_机器学习_08

这样便可以计算出每一个参数值,把这些参数值存在计算机中,下次计算时,直接把句子对应的参数值乘起来就是这句话的概率。这显然要比一元语言模型要好。对于其他高阶语言模型,思考方式类似,相信读者对语言模型有了一定的理解。