在NLTK Python的朴素贝叶斯分类器中使用文档长度

我正在使用Python中的NLTK构建垃圾邮件过滤器。我现在检查单词的出现并使用NaiveBayesClassifier,得到.98和F的准确度为.92的垃圾邮件和非垃圾邮件:0.98。但是,在检查我的程序错误的文档时,我注意到很多被归类为非垃圾邮件的垃圾邮件都是非常短的邮件。 所以我想把文档的长度作为NaiveBayesClassifier的一个特性。问题是它现在只处理二进制值。有没有其他方法可以做到这一点比例如:长度< 100 =真/假? (p.s.我构建了类似于http://nltk.googlecode.com/svn/trunk/doc/book/ch06.html示例的垃圾邮件检测程序)     
已邀请:
NLTK的朴素贝叶斯实现并没有这样做,但你可以将NaiveBayesClassifier的预测与文档长度的分布相结合。 NLTK的prob_classify方法将为您提供给定文档中单词的类的条件概率分布,即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)所需要的东西。     
有一些MultiNomial NaiveBayes算法可以处理范围值,但不能在NLTK中实现。对于NLTK NaiveBayesClassifier,您可以尝试将两个不同长度的阈值作为二进制功能。我还建议尝试使用Maxent分类器来查看它如何处理较小的文本。     

要回复问题请先登录注册