NLTK FreqDist对象比较

3 投票
2 回答
1171 浏览
提问于 2025-04-17 22:08

我刚接触Python,看到一个使用NLTK的代码示例,如下所示(在IDLE中):

>>> letters = nltk.FreqDist('ageqwst')
>>> words = nltk.corpus.words.words()
>>> [word for word in words if nltk.FreqDist(word) <= letters]

这个代码的输出显示了可以用letters中的字符组成的单词。

我想知道nltk.FreqDist(word) <= letters这一部分是怎么工作的。

我查了一下关于FreqDist的NLTK文档,但没有找到让我满意的答案。我发现type(letters)返回的是nltk.probability.FreqDist类的一个对象,我想知道在Python中这个对象的比较是怎么实现的。

Python有没有类似JAVA中compareTo的可重写方法呢?

谢谢,

2 个回答

0

基本上,我们会得到一个字典,这个字典的每个字符都是一个键,而这个字符在单词中出现的次数(频率)就是它的值。所以如果我们有:

fdist = nltk.FreqDist('abcdefg')

我们会得到:

FreqDist({'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1,'f': 1, 'g': 1})

这样,每个字母只出现一次。接下来,如果我们使用:

wordlist = nltk.corpus.words.words()

我们将得到一个完整的单词库,可以用来和我们的样本频率字典进行比较。现在如果写这个列表推导式

[w for w in wordlist if nltk.FreqDist(w) <= fdist]

我们会得到一大堆由我们字符串 'abcdefg' 中的字母组合而成的单词,每个字母出现的次数不会超过在频率字典 fdist 中给出的次数。输出的形式是:

['a','abed','ace','ad','ade','ae','age','aged','b','ba','bac','bad','bade',...]
3

FreqDist.__init__(samples) 这个构造函数会创建一个 dict(字典),其中:

  • 键(key)是样本(sample)
  • 值(value)是样本的计数(频率)

所以在你的例子中:

nltk.FreqDist('ageqwst')
<FreqDist: 'a': 1, 'e': 1, 'g': 1, 'q': 1, 's': 1, 't': 1, 'w': 1>

然后在你的 列表推导式 语句中,

[word for word in words if nltk.FreqDist(word) <= letters]

它对语料库中的每个单词做了同样的事情,因此现在它有两个 FreqDist 字典 可以和你的 if 条件进行比较。给定操作符 <=,它在寻找频率小于或等于(显而易见)样本 letters 中的单词。这里需要注意的是小于这一点。这使得它可以 跳过 样本中不包含的字母。

所以如果我们把操作符改得更明确一些,

[word for word in words if nltk.FreqDist(word) == letters]

它会返回一个空列表,因为在提供的语料库中没有任何单词出现次数与样本 'ageqwst' 相同。

举个例子:

words = nltk.corpus.words.words()
foo = nltk.FreqDist('foo')

print [word for word in words if nltk.FreqDist(word) <= foo]
>>> ['f', 'foo', 'o', 'of', 'of']

这里没有意外,我们也看到原始样本('foo')也出现在列表中,所以如果我们把操作符改得更明确一些,

print [word for word in words if nltk.FreqDist(word) == foo]
>>> ['foo']

我们会得到一个只有与我们样本分布完全相同的单词的列表。

最后一个例子:

words = nltk.corpus.words.words()
bar = nltk.FreqDist('bar')

print [word for word in words if nltk.FreqDist(word) <= bar]
>>> ['a', 'ar', 'b', 'ba', 'bar', 'bra', 'r', 'ra', 'rab', 'a']

我们仍然看到我们的样本('bar')出现在列表中,但是,还有两个其他单词与我们的样本分布相同,所以如果我们,

print [word for word in words if nltk.FreqDist(word) == bar]
>>> ['bar', 'bra', 'rab']

我们仍然得到原始样本('bar')加上两个其他的样本变体,'bra' 和 'rab'。这突显了样本的顺序是无关紧要的,这与 Python 映射类型 的行为是一致的。

我强烈建议你阅读一下 NLTK 书籍。是的,它很长,有时也比较枯燥,但它深入讲解了不同模块的理论和方法。所以根据你提问的兴趣程度,我觉得你会觉得它很有启发性。

撰写回答