使用nltk中的tagset计算语音中的不同单词

时间:2018-03-11 09:12:09

标签: python nltk tokenize pos-tagger

我目前遇到了这个问题。

我被赋予了一个任务,即实现一个函数,该函数返回具有给定词性的不同单词的排序列表。我需要使用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'

我觉得我已经接近但我不知道自己做错了什么。

任何帮助将非常感谢。 谢谢。

1 个答案:

答案 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())]