Ошибка «Слишком много значений для распаковки» при обучении классификатора

#python #nltk

#python #nltk

Вопрос:

Я хотел бы классифицировать ряды слов каждой строки столбца. Я определил функцию, которая возвращает словарь из каждой серии, положительные и отрицательные словари и train_set. Но когда я начал определять классификатор, код вылетает на этом уровне.

У меня есть этот код:

 import nltk.classify.util
from nltk.classify import NaiveBayesClassifier

def word_feats(words, val): 
    return {word: val for word in words}

voc_pos = [ 'beauty', 'good', 'happy']
voc_neg = [ 'bad', 'sick','lazy']

feat = {}
pos_feats = word_feats(voc_pos, 'pos') 
neg_feats = word_feats(voc_neg, 'neg')
train_set = {**pos_feats, **neg_feats}

classifier = NaiveBayesClassifier.train(train_set) 
  

Полная трассировка ошибок:

 Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/ion/.local/lib/python3.6/site-packages/nltk/classify/naivebayes.py", line 206, in train
    for featureset, label in labeled_featuresets:
ValueError: too many values to unpack (expected 2)
  

Комментарии:

1. @AkshayNevrekar Это строка в nltk .

Ответ №1:

Причина довольно проста: NaiveBayesClassifier ожидается итеративное значение 2, tuples состоящее из набора функций и метки.

Например, в вашем контексте положительное слово featureset будет выглядеть примерно так:

 [({'beauty': 0.2}, 'pos'),
 ({'good': 0.3}, 'pos'),
 ({'happy': 0.4}, 'pos')]
  

Соответственно, данные, которые вы должны передавать NaiveBayesClassifier , должны иметь такую форму:

 labelled_featuresets = [({'beauty': 0.2}, 'pos'),
                        ({'good': 0.3}, 'pos'),
                        ({'happy': 0.4}, 'pos'),
                        ({'bad': 0.5}, 'neg'),
                        ({'sick': 0.3}, 'neg'),
                        ({'lazy': 0.2}, 'neg')]

classifier = NaiveBayesClassifier.train(labelled_featuresets)
  

Однако, если вы посмотрите на более широкий контекст того, что вы делаете, я не уверен, что это действительно имеет смысл, по нескольким причинам.

Основная из них заключается в том, что на самом деле у вас нет способа решить, каковы эти оценки в первую очередь. Похоже, вы проводите анализ настроений; самый простой и распространенный способ — загрузить предварительно подготовленное сопоставление слов с оценками настроений, чтобы вы могли попробовать это.

Во-вторых, набор функций подразумевается как сопоставление значений функций с метками. Если вы посмотрите на официальный пример nltk, набор функций выглядит примерно так:

 [({'last_letter': 't'}, 'female'),
 ({'last_letter': 'a'}, 'female'),
 ({'last_letter': 'h'}, 'female'),
 ({'last_letter': 'l'}, 'female'),
 ({'last_letter': 'a'}, 'female'),
 ({'last_letter': 'a'}, 'female'),
 ({'last_letter': 'e'}, 'female'),
 ({'last_letter': 'r'}, 'male'),
 ({'last_letter': 'a'}, 'male'),
 ({'last_letter': 'n'}, 'female')]
  

Рабочий процесс здесь берет имя, генерирует из него один объект (последнюю букву), а затем использует последнюю букву каждого имени в сочетании с тем, является ли оно мужским или женским (метка), чтобы определить условную вероятность пола имени с учетом его последней буквы.

С другой стороны, то, что вы делаете, пытается решить, является ли предложение положительным или отрицательным, что означает, что вам нужно (упрощая здесь) определить, является ли каждое отдельное слово положительным или отрицательным. Однако, если это так, то и ваша функция, и ваша метка означают одно и то же!

Комментарии:

1. спасибо за это объяснение, вы гораздо лучше разъяснили мне проблему

2. Я внес эти изменения, и это работает: def word_feats(word): return {word: True} voc_pos = [‘красота’, ‘хороший’, ‘счастливый’] voc_neg = [‘плохой’, ‘больной’, ‘ленивый’] pos_feats = [(word_feats(pos), ‘pos’) для pos в voc_pos] neg_feats = [(word_feats(neg), ‘neg’) для neg в voc_neg]