2016-03-14 3 views
1

Я пытаюсь оценить точность классификации наивных байесовских обзоров nltk.Ошибка перекрестной проверки

from nltk.corpus import movie_reviews 
import random 
import nltk 
from sklearn import cross_validation 
from nltk.corpus import stopwords 
import string 
from nltk.classify import apply_features 

def document_features(document): 
    document_words = set(document) 
    features = {} 
    for word in unigrams: 
     features['contains({})'.format(word)] = (word in document_words) 
    return features 

documents = [(list(movie_reviews.words(fileid)), category) 
      for category in movie_reviews.categories() 
      for fileid in movie_reviews.fileids(category)] 
random.shuffle(documents) 
stop = stopwords.words('english') 
all_words = nltk.FreqDist(w.lower() for w in movie_reviews.words() if w.lower() not in stop and w.lower() not in string.punctuation) 
unigrams = list(all_words)[:200] 
featuresets = [(document_features(d), c) for (d,c) in documents] 

Я пытаюсь выполнить 10-кратное перекрестное подтверждение, и я привел пример из sklearn.

training_set = nltk.classify.apply_features(featuresets, documents) 
cv = cross_validation.KFold(len(training_set), n_folds=10, shuffle=True, random_state=None) 

for traincv, testcv in cv: 
    classifier = nltk.NaiveBayesClassifier.train(training_set[traincv[0]:traincv[len(traincv)-1]]) 
    result = nltk.classify.util.accuracy(classifier, training_set[testcv[0]:testcv[len(testcv)-1]]) 
    print 'Accuracy:', result 

Но я получаю сообщение об ошибке в строке

classifier = nltk.NaiveBayesClassifier.train(training_set[traincv[0]:traincv[len(traincv)-1]]) 

«список» объект не вызываемая

Любые идеи, что я делаю неправильно?

ответ

1

Фактическая ошибка лежит в этой строке:

training_set = nltk.classify.apply_features(featuresets, documents) 

featuresets список Python жалуется.

Из документации nltk.classify.apply_features:

apply_features (feature_func, TOKS, помеченный = None)

Используйте LazyMap класс для построения ленивого списка подобных объекта, аналогичный map(feature_func, toks) , В частности, если labeled=False, то возвращаемый список, как значение объекта равно:

[feature_func(tok) for tok in toks] 

Если labeled=True, то значения возвращаемого списка типа объекта равны:

[(feature_func(tok), label) for (tok, label) in toks] 

Поведение аналогично map, эта функция ожидает функцию (функция extractor) в качестве первого аргумента, который будет применен к e очень элемент (документ) списка, который передается как второй аргумент. Он возвращает LazyMap, который применяет функцию по требованию для сохранения памяти.

Но вы передали список наборов функций в apply_features вместо функции выделения функции. Таким образом, существует два возможных решения, чтобы сделать вещи работать, как вы хотите, чтобы они:

  1. Отбросить training_set и использовать featuresets вместо этого.
  2. Отменить featuresets и использовать training_set = nltk.classify.apply_features(document_features, documents, True) (обратите внимание на третий параметр).

Я рекомендую второй вариант, так как он не создает список функций всех документов в памяти.

+0

Большое спасибо за ваш ответ! Он работал, если я удаляю 'training_set = nltk.classify.apply_features (featuresets, documents)' и говорю 'training_set = featuresets'. Будет ли мне это использовать все функции документа, а не только 200 униграмм? С 'training_set = nltk.classify.apply_features (featuresets, documents, True) 'Я получаю ту же ошибку. – student

+0

Прошу прощения: Второй путь должен быть: 'training_set = nltk.classify.apply_features (document_features, documents, True)' (используйте функцию экстрактора функции вместо фактического результата). Тем не менее, вы всегда будете использовать 200 лучших униграмм, поскольку вы определили их как свои логические функции. Если вы будете использовать все слова, появляющиеся в любом документе, пространство с функциями будет чрезвычайно большим. – Callidior

Смежные вопросы