Подтвердить что ты не робот

Внедрение классификатора наивного байеса в НЛТК

У меня в основном есть тот же вопрос, что и этот парень. пример в книге NLTK для классификатора Наивного Байеса учитывает только, происходит ли слово в документе как функция. он не учитывает частоту слов как функцию, на которую следует смотреть ( "сумка слов" ).

Один из ответов кажется, что это невозможно сделать со встроенными классификаторами NLTK. Это так? Как я могу выполнять классификацию по частоте/сумме слов с NLTK?

4b9b3361

Ответ 1

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

Как заметил Кен в комментариях, NLTK имеет красивую упаковку для классификаторов scikit-learn. Модифицированный из документов, здесь несколько сложный, который делает TF-IDF-взвешивание, выбирает 1000 лучших функций на основе статистики chi2, а затем передает это в мультиномиальный наивный классификатор Байеса. (Держу пари, это несколько неуклюжий, поскольку я не очень хорошо знаком ни с 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())

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

Confusion matrix:
524     376
202     698

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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