我正在尝试使用Python NLTK通过Kneser-Ney平滑来平滑一组n-gram概率。
不幸的是,整个文档很少。

我想做的是:我将文本解析为三元组元组的列表。从此列表中,我创建一个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实现吗?我真的不想自己实现它。

最佳答案

Kneser-Ney(也可以查看 Goodman and Chen 对不同平滑技术的一个很好的调查)是一个非常复杂的平滑,只有我知道的几个包是正确的。不知道任何 python 实现,但是如果您只需要概率等,您绝对可以尝试 SRILM

  • 很有可能您的样本中有未出现在训练数据中的词(又名词外 (OOV) 词),如果处理不当,可能会弄乱您得到的概率。也许这会导致异常大和无效的概率?
  • 关于python - 使用Python NLTK的Trigram的Kneser-Ney平滑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35242155/

    10-13 00:04