详解kenlm语言模型计算过程

1.kenlm在python中的使用过程

import kenlm

model = kenlm.language("tri_gram_language_model.arpa")
score = model.score("银行 放贷 行为")
print(score)  
---------------------------------
>>> -7.153961658477783


score = model.score("银行 放待 行为")
print(score)  
----------------------------------
>>> -11.517741203308105

上述代码几个要点:

(1)tri_gram_language_model.arpa为训练好的n-gram语言模型,此处是我自己利用一个很小的文本训练出来的3-gram语言模型,模型文件内容如下,因为我这里训练的是3-gram语言模型,所以模型文件中,分别对应1-gram、2-gram及3-gram的模型参数。

                                                                                                       图1

(2)模型文件参数说明,以1-gram中的“-4.405105    中广网    -0.07266096”作为说明,数字“-4.405105”可以看成是“中广网”这个词出现的概率,然后取10为底的对数得到,即lg(p(中广网))=-4.405105,数字“ -0.07266096”为回退概率(back probability),在计算2-gram的未登录词会用到它,这里不用太过关注,需要额外了解的,可以参考这篇博文图解N-gram语言模型的原理。值得说明的是,对于3-gram中的参数,没有回退概率这样一项参数,这是因为本模型最多是3-gram,而回退概率是在计算4-gram才会用到,所以3-gram参数中不需要这一列。

(3)model.score("银行 放贷 行为")返回结果表示“银行 放贷 行为”这句话是人话的概率,也就是说返回分数越高,这句话就越像人话,分数越低,这句话就越不像人话,也就是越不符合我们日常的表达;从上面例子可以看到“银行 放贷 行为”比“银行 放待 行为”更符合人话

(4)model.score() 传入句子时,不同词语之间需要用空格隔开(即分词后的句子)

2.kenlm概率的具体计算过程

(1)语言模型概率——链式法则回顾

计算一个句子(w1,w2,w3,w4,w5)的概率可以用下式表示:

p(w1)p(w2|w1)p(w3|w1, w2)p(w4|w1,w2,w3)p(w5|w1,w2,w3,w4)
通过马尔科夫假设,将上述计算转化为3-gram模型,也就是计算某一个单词概率时,只依赖前面的2个词语,具体公式如下:

p(w1)p(w2|w1)p(w3|w1, w2)p(w4|w2,w3)p(w5|w3,w4)

(2)kenlm实际上就是通过上述模型进行计算(以计算“银行 放贷 行为”这句话概率为例)

  • 首先在句子前后添加<s>和</s>标记,最终需要计算的句子为['<s>', "银行", "放贷", "行为", "</s>"]
  • 然后根据模型参数计算句子概率:p(<s> 银行 放贷 行为 </s>)=p(<s>)p(银行|<s>)p(放贷|<s> 银行)p(行为|银行 放贷)p(</s>|放贷 行为)
  • 因为对于所有句子p(<s>)相同,上述可以转化为p(<s> 银行 放贷 行为 </s>)=p(银行|<s>)p(放贷|<s> 银行)p(行为|银行 放贷)p(</s>|放贷 行为)
  • 然后在模型文件中查找对应的概率参数计算即可,p(<s> 银行 放贷 行为 </s>)=-2.662721-2.953046-0.702558-0.835635=-7.15396
  • 读到这里你可能会有疑问,这些参数是怎么来的,如果有未登录词该怎么办?请接着往下看

(3)条件概率计算规则

  • 一元组w1,即p(w1)

    直接在arpa文件中查找,如果有则直接返回它的pro(图1中第一列参数),否则返回<unk>的pro(图1中第一列参数)。

  •  二元组w1w2,即p(w2|w1)

    直接在arpa文件中查找,有则直接返回它的pro,否则返回back_pro(w1) + pro(w2)的结果。back_pro为图2中第一列参数

  •  三元组w1w2w3,即p(w3|w1,w2)

                这个稍微复杂,具体参照下图

                                                                

(4)具体计算过程

计算可能用到的n-gram参数如下:

   pro            n-gram     back-pro

-4.540702	     <unk>	      0
0	              <s>	  -0.39536887
-2.7043288	      银行	  -0.15291257
-4.247026	      放贷	  -0.07266093
-3.3257697	      行为	  -0.18192981
-1.4688878	      </s>	       0


-2.662721	    <s> 银行    -0.0610168
-2.8920295	    银行 放贷	-0.0610168
-1.1110907	    放贷 行为	-0.0610168
-0.77461904	    行为 </s>	0


-0.7025586	  银行 放贷 行为

p(<s> 银行 放贷 行为 </s>)=p(银行|<s>)p(放贷|<s> 银行)p(行为|银行 放贷)p(</s>|放贷 行为)

p(银行|<s>) = -2.662721

p(放贷|<s> 银行) = -0.0610168-2.8920295 = -2.953046 (因为"<s> 银行 放贷"三元组参数不存在,最终结果等于back_pro("<s> 银行") + pro("银行 放贷"))

p(行为|银行 放贷) = -0.7025558

p(</s>|放贷 行为) = -0.0610168-0.77461904= -0.835635 (因为"放贷 行为 </s>"三元组参数不存在,最终结果等于back_pro("放贷 行为") + pro("行为 </s>"))

最终结果为  -2.662721 - 2.953046 - 0.7025558 - 0.835635 = - 7.15396

    

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值