我目前遇到了这个问题。
我被赋予了一个任务,即实现一个函数,该函数返回具有给定词性的不同单词的排序列表。我需要使用NLTK的pos_tag_sents和NLTK的tokeniser来计算特定的单词。
我有一个类似的问题,并得到它的工作感谢来自Stack Overflow的其他用户的一些帮助。并尝试使用相同的方法来解决这个问题。
以下是我目前在代码中的内容:
import nltk
import collections
nltk.download('punkt')
nltk.download('gutenberg')
nltk.download('brown')
nltk.download('averaged_perceptron_tagger')
nltk.download('universal_tagset')
def pos_counts(text, pos_list):
"""Return the sorted list of distinct words with a given part of speech
>>> emma = nltk.corpus.gutenberg.raw('austen-emma.txt')
>>> pos_counts(emma, ['DET', 'NOUN'])
[14352, 32029] - expected result
"""
text = nltk.word_tokenize(text)
tempword = nltk.pos_tag_sents(text, tagset="universal")
counts = nltk.FreqDist(tempword)
return [counts[x] or 0 for x in pos_list]
有一个doctest应该给出结果:[14352,32029]
我运行了我的代码并收到了此错误消息:
Error
**********************************************************************
File "C:/Users/PycharmProjects/a1/a1.py", line 29, in a1.pos_counts
Failed example:
pos_counts(emma, ['DET', 'NOUN'])
Exception raised:
Traceback (most recent call last):
File "C:\Program Files\JetBrains\PyCharm Community Edition 2017.3.4\helpers\pycharm\docrunner.py", line 140, in __run
compileflags, 1), test.globs)
File "<doctest a1.pos_counts[1]>", line 1, in <module>
pos_counts(emma, ['DET', 'NOUN'])
File "C:/Users/PycharmProjects/a1/a1.py", line 35, in pos_counts
counts = nltk.FreqDist(tempword)
File "C:\Users\PycharmProjects\a1\venv\lib\site-packages\nltk\probability.py", line 108, in __init__
Counter.__init__(self, samples)
File "C:\Users\AppData\Local\Programs\Python\Python36-32\lib\collections\__init__.py", line 535, in __init__
self.update(*args, **kwds)
File "C:\Users\PycharmProjects\a1\venv\lib\site-packages\nltk\probability.py", line 146, in update
super(FreqDist, self).update(*args, **kwargs)
File "C:\Users\AppData\Local\Programs\Python\Python36-32\lib\collections\__init__.py", line 622, in update
_count_elements(self, iterable)
TypeError: unhashable type: 'list'
我觉得我已经接近但我不知道自己做错了什么。
任何帮助将非常感谢。 谢谢。
答案 0 :(得分:2)
这样做的一种方法是:
import nltk
def pos_count(text, pos_list):
sents = nltk.tokenize.sent_tokenize(text)
words = (nltk.word_tokenize(sent) for sent in sents)
tagged = nltk.pos_tag_sents(words, tagset='universal')
tags = [tag[1] for sent in tagged for tag in sent]
counts = nltk.FreqDist(tag for tag in tags if tag in pos_list)
return counts
在nltk book中已经很好地解释了这一点。测试:
In [3]: emma = nltk.corpus.gutenberg.raw('austen-emma.txt')
In [4]: pos_count(emma, ['DET', 'NOUN'])
Out[4]: FreqDist({'DET': 14352, 'NOUN': 32029})
编辑:当您需要计算词性标记等内容时,使用FreqDist
是一个好主意。我不认为让函数返回带结果的普通列表非常聪明,原则上你怎么知道哪个数字代表哪个标签?
可能(imho bad)解决方案是返回FreqDist.values()
的排序列表。这样,结果按照标签名称的字母顺序排序。如果您真的希望在上面函数的定义中将return counts
替换为return [item[1] for item in sorted(counts.items())]
。