从零开始学Python自然语言处理(十六)—— 统计语言模型(上)

浏览: 2793

前文传送门:

从零开始学自然语言处理(十五)—— fasttext-pytorch代码实现

在说统计语言模型之前,我们先来看看语言模型是什么。

语言模型是描述自然语言规律的数学模型,可以判断一个句子是否合理。

比如:“我正在吃饭” 就比 “饭正在吃我” 合理。

语言模型大致经历了三个发展阶段:专家语法规则模型、统计语言模型、神经网络语言模型。

最初的专家语法规则模型,可以理解为相关领域的专家归纳语法的情况,制定规则,但是自然语言本身的多样性导致语法规则越来越多,规则的通用性和可持续性较差。

我们今天讲讲统计语言模型,是基于统计学的思想的。用它可以计算一个句子出现的概率。所以直观地理解是:统计语言模型其实就是计算句子出现概率的模型。

假定有个句子S,S由一串特定顺序排列的n个词组成(注意,在中文里我们看词,而不是字),ω1,ω2,...,ωn。我们想知道S这个句子在文章中出现的可能性,想计算S的概率P(S),也就是计算

P(S)=P(ω1,ω2,...,ωn)。

如果你还记得概率论里面的条件概率,就可以很快想到该概率计算可以展开为:

P(S)=P(ω1,ω2,...,ωn)

=P(ω1)*P(ω2|ω1)*P(ω3|ω1,ω2)...P(ωn|ω1,ω2,...,ωn-1)  。

如果你对这个公式感到陌生,肯定还记得这个P(AB)=P(A)*P(B|A),也就是上面公式n=2时的情况,那么当n=3时,

P(ABC) 

= P(AB)*P(C|AB)=P(A)*P(B|A)*P(C|AB),

随着n增长,上面的公式也就可以推导出来了。

我们举个例子,如果现在有一篇文章,我们需要计算一句话"我爱数据科学杂谈"出现的可能性,此时S=“我爱数据科学杂谈”,那么这句话出现的概率可以表示为P("我爱数据科学杂谈"),将句子分词后

P("我爱数据科学杂谈")

=P("我","爱","数据科学","杂谈")

=P("我")*P("爱"|"我")*P("数据科学"|"我","爱")*P("杂谈"|"我","爱","数据科学"),

该展开部分套用上面我们推出来的公式即可。

则问题归结为求上面每个部分的概率,例如求解

P("爱"|"我")=P("我爱")/P("我"),

其中P("我爱")计算方法是在语料库中统计“我爱”出现的次数,并除以语料库所有词个数。P("我")的计算方法类似。

所以是不是很简单呢?确实,计算方法很简单,但是这个计算方法有如下问题:

当词组合的越多,在语料库中该组合出现的情况越少,例如在语料库中“我爱数据科学杂谈”出现的次数比“我爱”少,当P(S)展开式中有一个词的组合没出现过,因为整个计算公式是连乘积,则整个句子的计算P(S)会变为0,也就是数据严重稀疏的问题 。

为了解决这个问题 ,N-gram模型被提出来了,他是一种统计语言模型,我们之前说了,统计语言模型其实就是计算句子出现概率的模型。那么在N-gram模型中,句子出现的概率计算公式被简化了,因为它引入了假设,我们都知道,当为了使用模型简化计算实际情况时,往往会引入假设,N-gram引入的假设如下:

当前词的出现只与前面N-1个词相关,而与其它任何词都不相关,整句句子的概率就是各个词出现概率的乘积,这个假设被称为马尔科夫假设。

如果你不好理解,我们举个例子你就懂了。

假设 N=2,当前词的出现只和之前2-1,也就是前1个词有关系,那么

P("我爱数据科学杂谈")

=P("我")*P("爱"|"我")*P("数据科学"|"爱")*P("杂谈"|"数据科学"),

也就是说“爱”的出现只和“我”有关系,“数据科学”的出现只和“爱”有关系。

假设 N=3,当前词的出现只和之前3-1,也就是前2个词有关系,那么

P("我爱数据科学杂谈")

=P("我")*P("爱"|"我")*P("数据科学"|"我","爱")*P("杂谈"|"爱","数据科学"),

也就是说“数据科学”的出现只与“我”和“爱”两个词相关,至于“爱”的出现本应该和前两个词相关,但由于“爱”的前面只有一个词,所以“爱”的出现只与“我”相关。

我们刚举例的N=2和N=3分别叫做Bi-gram和Tri-gram。

假设我们现在的语料由3句话组成:

"我爱数据科学杂谈"。

"我爱中国"。

"你爱数据挖掘"。

我们使用Bi-gram模型来计算“我爱数据科学杂谈”这句话出现的概率。

P("我爱数据科学杂谈")

=P("我")*P("爱"|"我")*P("数据科学"|"爱")*P("杂谈"|"数据科学")

我们先将语料分词处理(这里加空格表示):

"我 爱 数据科学 杂谈"。

"我 爱 中国"。

"你 爱 数据挖掘"。

P("我")出现在了句子开头,计算方法是计算其在语料库中出现在句子开头的频率,也就是2/3。

P("爱"|"我")=P("我爱")/P("我"),

“我”出现了2次,“我爱”出现了2次,

所以P("爱"|"我")=2/2=1。

类似的,计算出

P("数据科学"|"爱")=1/3,

P("杂谈"|"数据科学")=1/1=1。

P("我爱数据科学杂谈")

=(2/3)*1*(1/3)*1=2/9

当然,我们这里只是为了演示Bi-gram计算过程 ,有兴趣你可以使用Tri-gram计算一下,我们这里的语料库只有三句话也是为了方便演示计算方式,实际上,语料库是很大的。

当我们想要计算P("我爱数据科学理论")这段话的概率时,我们使用Tri-gram将其简化为

P("我爱数据科学理论")

=P("我")*P("爱"|"我")*P("数据科学"|"爱")*P("理论"|"数据科学")

=(2/3)*1*(1/3)*0=0

因为我们发现,语料库中,没有“数据科学理论”这样的组合。虽然已经将词的组合降到了最长为2,消除了语料库中不出现的长词组合对计算句子概率的影响 ,但还是有可能计算的句子整体概率为0,但实际上,语料库可能确实没有覆盖到某种词的组合,但这种词的组合可能是客观存在的,所以我们不能强行说这个句子出现的概率为0,所以Bi-gram简化了计算并且降低了数据稀疏的情况,但是并没有完全解决由于语料库中没有词的组合导致句子计算结果为0的事实。这时候人们想到了一种不错的办法解决这个问题...

欲知后事如何,请等下次文章连载。

统计语言模型的内容还没有结束。

扫码下图关注我们不会让你失望!

image.png

推荐 0
本文由 ID王大伟 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册