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) 所需的内容。