2012-04-11 5 views
23

У меня в основном есть same question as this guy .. example in the NLTK book для классификатора Наивного Байеса учитывает только то, происходит ли слово в документе как функция .. он не учитывает частоту слов как функция, на которую можно смотреть («сумка слов»).Реализация мешковины Классификатор Naive-Bayes в NLTK

One of the answers, похоже, это не может быть сделано со встроенными классификаторами NLTK. Это так? Как я могу использовать классификацию NB/пакет слов с NLTK?

ответ

31

scikit-learn имеет an implementation of multinomial naive Bayes, что является правильным вариантом наивного Байеса в этой ситуации. Однако векторная машина поддержки (SVM) будет работать лучше.

Как отметил Кен в комментариях, NLTK имеет a nice wrapper for scikit-learn classifiers. Модифицированный из документов, вот несколько сложный, который делает TF-IDF-взвешивание, выбирает 1000 лучших функций, основанных на статистике chi2, а затем передает это в мультиномиальный наивный классификатор Байеса. (. Я держал пари, что это несколько неуклюже, так как я не очень знакомы ни с NLTK или scikit учиться)

import numpy as np 
from nltk.probability import FreqDist 
from nltk.classify import SklearnClassifier 
from sklearn.feature_extraction.text import TfidfTransformer 
from sklearn.feature_selection import SelectKBest, chi2 
from sklearn.naive_bayes import MultinomialNB 
from sklearn.pipeline import Pipeline 

pipeline = Pipeline([('tfidf', TfidfTransformer()), 
        ('chi2', SelectKBest(chi2, k=1000)), 
        ('nb', MultinomialNB())]) 
classif = SklearnClassifier(pipeline) 

from nltk.corpus import movie_reviews 
pos = [FreqDist(movie_reviews.words(i)) for i in movie_reviews.fileids('pos')] 
neg = [FreqDist(movie_reviews.words(i)) for i in movie_reviews.fileids('neg')] 
add_label = lambda lst, lab: [(x, lab) for x in lst] 
classif.train(add_label(pos[:100], 'pos') + add_label(neg[:100], 'neg')) 

l_pos = np.array(classif.classify_many(pos[100:])) 
l_neg = np.array(classif.classify_many(neg[100:])) 
print "Confusion matrix:\n%d\t%d\n%d\t%d" % (
      (l_pos == 'pos').sum(), (l_pos == 'neg').sum(), 
      (l_neg == 'pos').sum(), (l_neg == 'neg').sum()) 

Это печатное для меня:

Confusion matrix: 
524  376 
202  698 

Не совершенным, но приличная, учитывая это не очень простая проблема, и она тренируется только на 100/100.

+1

На самом деле, он, вероятно, хочет, чтобы scikit-learn поддерживали модели Vector Machine. NLTK имеет красивую оболочку 'nltk.classify.scikitlearn.SklearnClassifier', которая делает эти классификаторы хорошо вписаны в его API. –

+0

@ KenBloom Да, SVM, вероятно, будет лучше, но он специально спросил о наивных байесах.:) Эта обертка хороша, и я просто понял, что есть также многомиллионный наивный Байес в scikit-learn, поэтому я изменю свой ответ, чтобы использовать это. – Dougal

+1

эта выглядит блестяще простой. Мне жаль, что я не научился питону, когда занимался своим Ph.D. в этом. В Ruby я много работал с классификаторами упаковки, что было бы совершенно ненужным. –

6

Характеристики классификатора заливок NLTK являются «номинальными», а не числовыми. Это означает, что они могут принимать конечное число дискретных значений (меток), но их нельзя рассматривать как частоты.

Так с классификатором Байеса, вы не можете непосредственно частота использования слова как feature-- вы могли бы сделать что-то вроде использовать 50 чаще слова из каждого текста как ваш набор функций, но это совсем другое дело

Но, возможно, в NLTK есть другие классификаторы, которые зависят от частоты. Я не знаю, но ты посмотрел? Я бы сказал, что стоит проверить.

3
  • поместить строку, которую вы смотрите на в список, разбитый на слова
  • для каждого элемента в списке, спросить: этот пункт особенность, которую я имею в моем списке функций.
  • Если это так, добавьте журнал проб как обычно, если нет, игнорируйте его.

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

Для дополнительной точности учитывайте все биграммы, три грамма и т. Д. Как отдельные функции.

Это помогает вручную создавать собственные классификаторы, чтобы вы точно понимали, что происходит, и что вам нужно делать, чтобы повысить точность. Если вы используете предварительно упакованное решение, и оно не работает достаточно хорошо, вы не можете с этим поделать.

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