Использование длины документа в наивном байесовском классификаторе NLTK Python - PullRequest
2 голосов
/ 09 марта 2011

Я создаю спам-фильтр, используя NLTK в Python. Теперь я проверяю наличие слов и использую NaiveBayesClassifier, что дает точность в 0,98 и меру F для спама 0,92 и не спама: 0,98. Однако при проверке документов, в которых обнаружены ошибки моей программы, я замечаю, что много спама, который классифицируется как не спам, являются очень короткими сообщениями.

Итак, я хочу указать длину документа в качестве функции для NaiveBayesClassifier. Проблема в том, что теперь он обрабатывает только двоичные значения. Есть ли другой способ сделать это, например, сказать: длина <100 = истина / ложь? </p>

(p.s. У меня есть детектор спама, аналогичный примеру http://nltk.googlecode.com/svn/trunk/doc/book/ch06.html)

Ответы [ 2 ]

3 голосов
/ 13 марта 2011

Реализация Naive Bayes в NLTK этого не делает, но вы можете объединить прогнозы NaiveBayesClassifier с распределением по длинам документов.Метод prob_classify от NLTK даст вам условное распределение вероятностей по классам с учетом слов в документе, т. Е. P (cl | doc).То, что вы хотите, это P (cl | doc, len) - вероятность класса с учетом слов в документе и его длины.Если мы сделаем еще несколько предположений о независимости, мы получим:

P(cl|doc,len) = (P(doc,len|cl) * P(cl)) / P(doc,len)
              = (P(doc|cl) * P(len|cl) * P(cl)) / (P(doc) * P(len))
              = (P(doc|cl) * P(cl)) / P(doc) * P(len|cl) / P(len)
              = P(cl|doc) * P(len|cl) / P(len)

Вы уже получили первый член из prob_classify, поэтому все, что осталось сделать, это оценить P (len | cl) и P (LEN).

Вы можете получить столько, сколько захотите, когда дело доходит до моделирования длин документов, но для начала вы можете просто предположить, что журналы длин документов обычно распределяются.Если вы знаете среднее значение и стандартное отклонение длины документа журнала в каждом классе и в целом, тогда легко вычислить P (len | cl) и P (len).

Вот один из способов оценкиP (len):

from nltk.corpus import movie_reviews
from math import sqrt,log
import scipy

loglens = [log(len(movie_reviews.words(f))) for f in movie_reviews.fileids()]
sd = sqrt(scipy.var(loglens)) 
mu = scipy.mean(loglens)

p = scipy.stats.norm(mu,sd)

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

p.cdf(log(L+1)) - p.cdf(log(L))

Условные распределения длины могут быть оценены таким же образом, используя длины журналов документов в каждом классе.Это должно дать вам то, что вам нужно для P (cl | doc, len).

3 голосов
/ 10 марта 2011

Существуют алгоритмы MultiNomial NaiveBayes, которые могут обрабатывать значения диапазона, но не реализованы в NLTK. Для NLTK NaiveBayesClassifier вы можете попробовать использовать несколько различных пороговых значений длины в качестве бинарных функций. Я бы также предложил попробовать Maxent Classifier, чтобы увидеть, как он обрабатывает текст меньшего размера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...