2011-03-09 4 views
2

Je construis un filtre anti-spam en utilisant le langage NLTK en Python. Je vérifie maintenant les occurrences de mots et utilise le NaiveBayesClassifier avec une précision de .98 et F mesure le spam de .92 et le non-spam: 0.98. Toutefois, lorsque je vérifie les documents dans lesquels mes erreurs de programme, je remarque que beaucoup de spams qui sont classés comme non-spam sont des messages très courts. Donc je veux mettre la longueur d'un document comme une caractéristique pour le NaiveBayesClassifier. Le problème est que maintenant il ne gère que les valeurs binaires. Y at-il un autre moyen de faire cela que par exemple dire: longueur < 100 = vrai/faux?Utilisation de la longueur du document dans le classificateur Naive Bayes de NLTK Python

(P.S. J'ai construire le détecteur de spam analogue à http://nltk.googlecode.com/svn/trunk/doc/book/ch06.html exemple)

Répondre

3

L'implémentation de Naive Bayes par NLTK ne le fait pas, mais vous pouvez combiner les prédictions de NaiveBayesClassifier avec une distribution sur des longueurs de document. La méthode prob_classify de NLTK vous donnera une distribution de probabilités conditionnelle sur les classes en fonction des mots du document, c'est-à-dire, P (cl | doc). Ce que vous voulez, c'est P (cl | doc, len) - la probabilité d'une classe étant donné les mots dans le document et sa longueur. Si nous faisons quelques hypothèses d'indépendance, nous obtenons:

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) 

Vous avez déjà le premier terme de prob_classify, donc tout ce qui reste à faire est d'estimer P (len | cl) et P (LEN) .

Vous pouvez obtenir autant de fantaisie que vous voulez quand il s'agit de modéliser des longueurs de document, mais pour commencer, vous pouvez simplement supposer que les journaux des longueurs de document sont normalement distribués. Si vous connaissez la moyenne et l'écart-type des longueurs de document dans chaque classe et dans l'ensemble, il est alors facile de calculer P (len | cl) et P (len).

est ici une façon de faire l'estimation 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) 

Les seules choses difficiles à retenir sont que cela est une distribution sur le log-longueurs plutôt que des longueurs et qu'il est une distribution continue. Ainsi, la probabilité d'un document de longueur L sera:

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

Les distributions de longueur conditionnelles peuvent être estimés de la même manière, en utilisant les log-longueurs des documents dans chaque classe. Cela devrait vous donner ce dont vous avez besoin pour P (cl | doc, len).

3

Il existe des algorithmes MULTINOMIAL de NaiveBayes qui peuvent gérer les valeurs de gamme, mais pas mis en œuvre dans NLTK. Pour le NLTK NaiveBayesClassifier, vous pouvez essayer d'avoir plusieurs seuils de longueur différents en tant que fonctions binaires. Je suggère également d'essayer un classificateur Maxent pour voir comment il gère le texte plus petit.

+0

merci pour vos conseils! – Javaaaa

Questions connexes