FreqDist с nltk: ValueError: слишком много значений для распаковки

Я пытался найти распределение частот существительных в данном предложении. Если я сделаю это:

text = "This ball is blue, small and extraordinary. Like no other ball."
text=text.lower()
token_text= nltk.word_tokenize(text)
tagged_sent = nltk.pos_tag(token_text)
nouns= []
for word,pos in tagged_sent:
    if pos in ['NN',"NNP","NNS"]:
        nouns.append(word)
freq_nouns=nltk.FreqDist(nouns)
print freq_nouns

Он считает "мяч" и "мяч". как отдельные слова. Итак, я пошел вперед и tokenized the sentence before tokenizing the words:

text = "This ball is blue, small and extraordinary. Like no other ball."
text=text.lower()
sentences = nltk.sent_tokenize(text)                        
words = [nltk.word_tokenize(sent)for sent in sentences]    
tagged_sent = [nltk.pos_tag(sent)for sent in words]
nouns= []
for word,pos in tagged_sent:
    if pos in ['NN',"NNP","NNS"]:
        nouns.append(word)
freq_nouns=nltk.FreqDist(nouns)
print freq_nouns

Это дает следующую ошибку:

Traceback (most recent call last):
File "C:\beautifulsoup4-4.3.2\Trial.py", line 19, in <module>
for word,pos in tagged_sent:
ValueError: too many values to unpack

Что я делаю неправильно? Пожалуйста помоги.

1 ответ

Решение

Вы были так близко!

В этом случае вы изменили свой tagged_sent из списка кортежей в список списков кортежей из-за вашего понимания списка tagged_sent = [nltk.pos_tag(sent)for sent in words],

Вот несколько вещей, которые вы можете сделать, чтобы узнать, какие у вас есть объекты:

>>> type(tagged_sent), len(tagged_sent)
(<type 'list'>, 2)

Это показывает, что у вас есть список; в этом случае 2 предложения. Вы можете дополнительно проверить одно из этих предложений, как это:

>>> type(tagged_sent[0]), len(tagged_sent[0])
(<type 'list'>, 9)

Вы можете видеть, что первое предложение представляет собой другой список, содержащий 9 пунктов. Ну, как выглядит один из этих предметов? Что ж, давайте посмотрим на первый элемент первого списка:

>>> tagged_sent[0][0]
('this', 'DT')

Если вам интересно увидеть весь объект, которым я часто бываю, вы можете спросить pprint (pretty-print) модуль, чтобы на него было приятнее смотреть так:

>>> from pprint import pprint
>>> pprint(tagged_sent)
[[('this', 'DT'),
  ('ball', 'NN'),
  ('is', 'VBZ'),
  ('blue', 'JJ'),
  (',', ','),
  ('small', 'JJ'),
  ('and', 'CC'),
  ('extraordinary', 'JJ'),
  ('.', '.')],
 [('like', 'IN'), ('no', 'DT'), ('other', 'JJ'), ('ball', 'NN'), ('.', '.')]]

Итак, длинный ответ - ваш код должен перебирать новый второй слой списков, например так:

nouns= []
for sentence in tagged_sent:
    for word,pos in sentence:
        if pos in ['NN',"NNP","NNS"]:
            nouns.append(word)

Конечно, это просто возвращает неуникальный список элементов, которые выглядят так:

>>> nouns
['ball', 'ball']

Вы можете создать уникальный список по-разному, но вы можете быстро, используя set() Структура данных, вот так:

unique_nouns = list(set(nouns))
>>> print unique_nouns
['ball']

Для ознакомления с другими способами, которыми вы можете уникально составить список предметов, см. Несколько более старый, но чрезвычайно полезный: http://www.peterbe.com/plog/uniqifiers-benchmark

Другие вопросы по тегам