scikit-learn ha an implementation of multinomial naive Bayes, che è la variante giusta di Bayes naive in questa situazione. Una macchina vettoriale di supporto (SVM) probabilmente funzionerebbe meglio, però.
Come ha sottolineato Ken nei commenti, NLTK ha a nice wrapper for scikit-learn classifiers. Modificato dai documenti, qui è un po 'complicato che fa la ponderazione TF-IDF, sceglie le 1000 migliori caratteristiche basate su una statistica chi2, e poi lo passa in un classificatore Bayes ingenuo multinomiale. (. Scommetto che questo è un po 'goffo, come io non sono super familiarità con uno o NLTK scikit-learn)
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())
Questo stampato per me:
Confusion matrix:
524 376
202 698
Non perfetto, ma decente, considerando non è un problema super facile ed è solo addestrato su 100/100.
In realtà, probabilmente desidera che i modelli di supporto per la macchina vettoriale supportino gli scikit. NLTK ha un bel wrapper 'nltk.classify.scikitlearn.SklearnClassifier' che rende questi classificatori adatti alla sua API. –
@KenBloom Sì, gli SVM probabilmente andrebbero meglio, ma ha fatto espressamente domande sull'ingenuo Bayes.:) Quel wrapper è bello, e ho appena realizzato che c'è anche un Baye ingenuo multinomiale in scikit-learn, quindi cambierò la mia risposta per usarlo. – Dougal
che sembra straordinariamente semplice. Vorrei aver imparato Python mentre stavo facendo il mio dottorato. in questo. Ho fatto un sacco di classificazioni per il wrapping del lavoro in Ruby che sarebbe stato del tutto inutile. –