NLTK FreqDist对象比较
我刚接触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 个回答
基本上,我们会得到一个字典,这个字典的每个字符都是一个键,而这个字符在单词中出现的次数(频率)就是它的值。所以如果我们有:
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',...]
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 书籍。是的,它很长,有时也比较枯燥,但它深入讲解了不同模块的理论和方法。所以根据你提问的兴趣程度,我觉得你会觉得它很有启发性。