我正在尝试使用Python NLTK和Kneser-Ney平滑算法来平滑一组n-gram概率。不幸的是,整个文档非常简略。
我要做的是:将文本解析为三元组列表。从列表中创建一个FreqDist,然后使用该FreqDist计算KN平滑分布。
我相当确定结果完全错误。当我总结各个概率时,得到的结果远远超过1。请看这段代码示例:
输出结果为"41.51696428571428"。根据语料库的大小,该值会无限增长。这使得prob()返回的不是概率分布。
从NLTK代码来看,我认为该实现存在问题。也许我不理解代码应该如何使用。如果是这种情况,您能给我一些提示吗?如果不是,请问您知道任何可用的Python实现吗?我真的不想自己实现。
我要做的是:将文本解析为三元组列表。从列表中创建一个FreqDist,然后使用该FreqDist计算KN平滑分布。
我相当确定结果完全错误。当我总结各个概率时,得到的结果远远超过1。请看这段代码示例:
import nltk
ngrams = nltk.trigrams("What a piece of work is man! how noble in reason! how infinite in faculty! in \
form and moving how express and admirable! in action how like an angel! in apprehension how like a god! \
the beauty of the world, the paragon of animals!")
freq_dist = nltk.FreqDist(ngrams)
kneser_ney = nltk.KneserNeyProbDist(freq_dist)
prob_sum = 0
for i in kneser_ney.samples():
prob_sum += kneser_ney.prob(i)
print(prob_sum)
输出结果为"41.51696428571428"。根据语料库的大小,该值会无限增长。这使得prob()返回的不是概率分布。
从NLTK代码来看,我认为该实现存在问题。也许我不理解代码应该如何使用。如果是这种情况,您能给我一些提示吗?如果不是,请问您知道任何可用的Python实现吗?我真的不想自己实现。
math.exp(41.51696428571428)
= 1.0729722613480671e+18,概率非常小。当它增长时,KN平滑也会变大,这意味着概率更小。但也可能是NLTK实现有问题,请向https://github.com/nltk/nltk/issues报告问题。 - alvas