db2中count(*) as cnt_n-gram语言模型-srilm-python中的平滑

65d6978c02842a6e21b202b0039ee1e5.png

先声明,srilm-python中计算出来的平滑值,跟我们看到的加1平滑公式算出来的不一样,感觉上,srilm的平滑计算不管是程序说明,还是文档说明,都很乱,甚至有时候跟我们见到的公式算出来的不一样。这里我们直接给出加法平滑的调用代码,至于另外6个平滑,直接改参数就可以了。后边,我们试试不用srilm-python,而直接用srilm的ngram-count,n-gram,如果依然对不上,那只能看看kenlm了,如果kenlm也对不上,我们放弃吧^_^。

首先,列出加法平滑公式

163d9393e8b85fc8d514fb255bf2d28a.png

输入的文本zcq_text.txt如下

$ cat zcq_text.txt
brown read holy bible
mark read a text book
he read a book by david

这个训练集是选自宗的《统计自然语言处理》。

下边我们用这个代码来计算句子brown read a book的2-gram加1平滑概率

import srilm.vocab
import srilm.stats
import srilm.discount
import srilm.ngram
import numpy as np

vocab = srilm.vocab.Vocab()
lm = srilm.ngram.Lm(vocab, 2)
stats = srilm.stats.Stats(vocab, 2)

# 读取训练集,构建词汇表
fname = 'data/zcq_text.txt'
# 读取词汇表
with open(fname) as infile:
    for line in infile:
        line = line.strip()
        if line:
            for w in line.split():
                vocab.add(w)
print("词汇表长度=", len(vocab))
# n-gram计数
stats.count_file(fname)
for index, cnt in stats:
    print(vocab.string(index), cnt)
for index, cnt in stats.iter(1):
    print(vocab.string(index), cnt)

# 设置平滑方法
for i in range(1, 3):
    lm.set_discount(i, srilm.discount.Discount(method='additive'))
lm.debug_level = 2
# 训练语言模型
lm.train(stats)

ngram2_li = [['<s>', 'brown'],
           ['brown', 'read'],
           ['read', 'a'], 
           ['a', 'book'],
           ['book', '</s>']]
for word_li in ngram2_li:
    logprob = lm.prob_ngram(vocab.index(word_li))
    prob = np.power(10,logprob)
    print(logprob, prob, word_li)

我们列出n-gram统计结果,n-gram统计是正确的,大家可以按照这些值以及平滑公式算算,结果跟程序计算的不一样。

['<s>', 'brown'] 1
['<s>', 'mark'] 1
['<s>', 'he'] 1
['brown', 'read'] 1
['read', 'holy'] 1
['read', 'a'] 2
['holy', 'bible'] 1
['bible', '</s>'] 1
['mark', 'read'] 1
['a', 'text'] 1
['a', 'book'] 1
['text', 'book'] 1
['book', '</s>'] 1
['book', 'by'] 1
['he', 'read'] 1
['by', 'david'] 1
['david', '</s>'] 1
['<s>'] 3
['</s>'] 3
['brown'] 1
['read'] 3
['holy'] 1
['bible'] 1
['mark'] 1
['a'] 2
['text'] 1
['book'] 2
['he'] 1
['by'] 1
['david'] 1

最后,附上程序运行结果

-1.1903316974639893 0.064516129137182 ['<s>', 'brown']
-0.8893017172813416 0.12903225367473986 ['brown', 'read']
-1.0142403841018677 0.09677420580692216 ['read', 'a']
-1.0142403841018677 0.09677420580692216 ['a', 'book']
-0.8893017172813416 0.12903225367473986 ['book', '</s>']

鹅厂同学,你能给我解释一下为什么吗?。还有个问题,就是同一份代码多次运行,居然结果会出现特别特别小的概率值,这都是啥稳定性呀,太不靠谱,以前用srilm源码写程序时候,倒是没遇到过这种问题,大家慎用srilm-python的ngram模块吧。

至于其他平滑方法,只需要修改 lm.set_discount(i, srilm.discount.Discount(method='additive')) 的method参数为'kneser-ney', 'good-turing', 'witten-bell', 'chen-goodman', 'absolute', 'additive', 'natural'。

如果srilm-python就只能提供一个n-gram计数的话,那还不如直接用HanLP呢,根本不需要再用srilm了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值