NLP-统计语言模型的平滑处理方法

1,211 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


一、引言

NLP-统计语言模型中简要介绍了统计语言模型的原理和实现方法,以bigram为例,计算了

P(,喜欢,自然语言,处理)=P()P(喜欢)P(自然语言喜欢)P(处理自然语言)P(\color{green}{我,喜欢 ,自然语言 ,处理})=P(\color{green}{我})*P(\color{green}{喜欢|我})*P(\color{green}{自然语言|喜欢})*P(\color{green}{处理|自然语言})

的概率,这是比较理想的情况,而现实与理想的差距是我们预测了一万种可能,却还有一万零一种可能的存在。而我们企图用已经存在的语料数据来覆盖未来有可能出现的测试数据,未免有些天真。 还是以NLP-统计语言模型中的假设语料来举例

  • 我 喜欢 大自然
  • 自然语言 是 如何 形成 的 呢
  • 如何 处理 数据 是 很 重要 的
  • 越来越多 的 人 喜欢 自然语言 处理

而我需要计算句子我喜欢看电影\color{green}{我 喜欢 看电影}的概率时:

P(,喜欢,看电影)=P()P(喜欢)P(看电影喜欢)P(\color{green}{我,喜欢 ,看电影})=P(\color{green}{我})*P(\color{green}{喜欢|我})*P(\color{green}{看电影|喜欢})

在语料库中喜欢的后面并没有出现过看电影,也就意味着P(看电影喜欢)=0P(\color{green}{看电影|喜欢})=0,直接导致了我喜欢看电影\color{green}{我 喜欢 看电影}的可能性为0,这显然是不科学的,所以就需要一些平滑的处理方法,用以过渡上述情况。

二、add-k smoothing

add-k smoothing 是一种比较简单的方式,为了防止出现概率为0的情况,对求概率的公式做了一点手脚,如下:

P(wnwn1)=wnwn1同时出现的次数+k语料库中wn1出现的次数+k词库大小(k=1,2,3...n) P(w_n|w_{n-1})=\frac{w_n、w_{n-1}同时出现的次数+k}{语料库中w_{n-1}出现的次数+k*词库大小} \tag{k=1,2,3...n}

为什么是k词库大小k*词库大小呢,因为要确保概率的总和为1,具体过程此处不做推导。 add-k smoothing 是一种行之有效的方式,但其中也隐含着一种价值观: 没有出现的词未来出现的可能性相等,对于所有概率为0的情况,都是在分子和分母上做了同样的操作,那么就导致了这些情况的概率都一致,是否还有更加“公平”的一些方式呢?有,来看看interpolation smoothing。

三、interpolation smoothing

interpolation smoothing的思想在于求上不得而求其中,其中不足余下来补,为了更好的说明interpolation 以trigram为例,假设我们要求P(wnwn1,wn2)P(w_n|w_{n-1},w_{n-2})P(wnwn1,wn2)P(w_n|w_{n-1},w_{n-2})会等于0,那么求P(wnwn1)P(w_n|w_{n-1}),再不济还可以求P(wn)P(w_n),综合上面三种情况,给每种情况分配不同的权重得:

P(wnwn1,wn2)=λ1P(wnwn1,wn2)+λ2P(wnwn1)+λ3P(wn)P(w_n|w_{n-1},w_{n-2})=\lambda_1 * P(w_n|w_{n-1},w_{n-2})+\lambda_2 * P(w_n|w_{n-1})+\lambda_3 * P(w_n) λ1+λ2+λ3=1\lambda_1+\lambda_2+\lambda_3=1

此方法综合unigram、bigram和trigram甚至可以更多,这样就确保了语料库未出现词组合的概率的不一致,相对来说,公平了些。

四、good-turing smoothing

good-turing的核心思想在于,对于没有出现的过的事件,不能认为该事件出现的概率为0,所以我们从已经发生的事件概率总量1中分配一个很小的比例给该事件。 这是一种很有前瞻性的格局,但是把概率分出去一分部以后,那未出现的事件+已经出现的事件的概率总和就会大于1,所以就需要把已经发生的事件的概率稍微调小一点,确保概率的总合为1,具体怎么调整呢,先摆出公式再来解释: 为了说明公式,先来认识一个概念:

Nc:表示语料库中出现了c次的词有NcN_c:表示语料库中出现了c次的词有N_c个 N1:表示语料库中出现了1次的词有N1N_1:表示语料库中出现了1次的词有N_1个 dc:表示调整以后语料库中出现了c次的词的频次d_c:表示调整以后语料库中出现了c次的词的频次 c:表示某个词在语料库中出现的频次c:表示某个词在语料库中出现的频次

假设语料库的大小为N,对于没有出现过的词,概率原本为0,那么分一个语料库中低频事件的概率给它,比如,把语料库中只出现只出现过一次的事件的概率给它:

P(未出现词)=0=>P(未出现词)=N1NP(未出现词)=0 =>P(未出现词)=\frac{N_1}{N}

对于已经出现过的词,需要调整概率

P(出现的词)=cN=>P(出现的词)=dc1N=(c+1)Nc+1NcNP(出现的词)= \frac{c}{N} =>P(出现的词)=d_c*\frac{1}{N}=\frac{(c+1)N_{c+1}}{N_c*N}

至于公式为何是这样,吴军老师在《数学之美》中讲解较好,感兴趣的可以前去参考,此处不做过多解释,本文着眼于如何利用成果解决问题。

看了公式可能有点蒙圈,还是根据语料库来解释一下 设语料来举例

  • 自然语言 是 如何 形成 的 呢
  • 如何 处理 自然语言 是 很 重要 的
  • 是 又 如何

假设现在要根据语料库计算计算的概率,而计算刚好没有出现过,那么

P(计算)=N116=616P(计算)=\frac{N_1}{16}=\frac{6}{16} \tag{只出现过一次的词有6个}

此时,原先出现过的词的概率需调整

P(自然语言)=cN=216=>(c+1)Nc+1NcN=(2+1)N2+1N2N=316P(自然语言)=\frac{c}{N}=\frac{2}{16}=>\frac{(c+1)N_{c+1}}{N_c*N}=\frac{(2+1)N_{2+1}}{N_2*N}=\frac{3}{16}

突然发现了神奇的一幕,调整以后概率还变大了,这是因为举例的语料库太小,很多地方不合理,在较大的语料库中是不会出现这种情况的,拿汉字来说,常用的汉字的比例在总汉字中的比例是很小的,也就是c越大,NcN_c越小,那么一般情况下Nc+1<NcN_{c+1}<N_{c}(具体证明参考齐夫定律),即概率调整后是减少的。

五、总结

本文简单介绍一些在统计语言模型中需要的一些平滑过渡的方法,总体而言就是考虑未登录词的情况,方法并非绝对,如果读者还有更多的方法欢迎介绍。