NLTKのNaiveBayesの実装はそれを行いませんが、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)を推定する1つの方法は次のとおりです。
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)に必要なものが得られるはずです。