我掌握了我的卦的频率分布,然后训练了Kneser-Ney。
当我检查不在kneser_ney.prob
中的三字母组合的list_of_trigrams
时,我得到零!我在做什么错了?
freq_dist = nltk.FreqDist(list_of_trigrams)
kneser_ney = nltk.KneserNeyProbDist(freq_dist)
它甚至在列表中有n-1-gram,这就是我想要的:
print(kneser_ney.prob(('ئامادەكاری', 'بۆ', 'تاقیكردنەوە')))
这就是列表中的
('ئامادەكاری', 'بۆ', 'كارە')
我已经在网上搜寻了所有与我有相同问题的人,但是我没有发现任何问题...
答案 0 :(得分:1)
我认为您所观察到的完全正常。
从Kneser-Ney smoothing的Wikipedia页面(方法部分):
请注意,p_KN是一个适当的分布,因为以上述方式定义的值是非负的,并且总和为1。
0
不在语料库中出现的概率为ngram
。
这是平滑的全部要点,用于将语料库中出现的ngram的一些概率质量重新分配给那些没有出现的ngram,以便最终不会得到一堆0的概率ngram。
上面的句子并不意味着通过 Kneser-Ney平滑,您选择的任何ngram的概率都将为非零,这意味着给定语料库,它将为现有ngram的方式,使您在以后的分析中有一定的 spare 概率可用于其他ngram。 这是您您必须为非出现的ngram指定的空闲概率,而不是 Kneser-Ney平滑所固有的东西。
仅出于完整性考虑,我报告代码以观察行为(主要取自here,并适用于Python 3):
import nltk
nltk.download('gutenberg')
nltk.download('punkt')
from nltk.util import ngrams
from nltk.corpus import gutenberg
gut_ngrams = tuple(
ngram for sent in gutenberg.sents()
for ngram in ngrams(
sent, 3, pad_left=True, pad_right=True,
right_pad_symbol='EOS', left_pad_symbol="BOS"))
freq_dist = nltk.FreqDist(gut_ngrams)
kneser_ney = nltk.KneserNeyProbDist(freq_dist)
prob_sum = 0
for i in kneser_ney.samples():
if i[0] == "I" and i[1] == "confess":
prob_sum += kneser_ney.prob(i)
print("{0}:{1}".format(i, kneser_ney.prob(i)))
print(prob_sum)
# ('I', 'confess', ','):0.26973684210526316
# ('I', 'confess', 'that'):0.16447368421052633
# ('I', 'confess', '.--'):0.006578947368421052
# ('I', 'confess', 'it'):0.03289473684210526
# ('I', 'confess', 'I'):0.16447368421052633
# ('I', 'confess', ',"'):0.03289473684210526
# ('I', 'confess', ';'):0.006578947368421052
# ('I', 'confess', 'myself'):0.006578947368421052
# ('I', 'confess', 'is'):0.006578947368421052
# ('I', 'confess', 'also'):0.006578947368421052
# ('I', 'confess', 'unto'):0.006578947368421052
# ('I', 'confess', '"--'):0.006578947368421052
# ('I', 'confess', 'what'):0.006578947368421052
# ('I', 'confess', 'there'):0.006578947368421052
# 0.7236842105263156
# trigram not appearing in corpus
print(kneser_ney.prob(('I', 'confess', 'nothing')))
# 0.0