B.2 训练朴素贝叶斯分类器
怎样学习概率 和 ?先考虑最大似然估计,也就是直接使用数据中的频率。对于类别先验 ,我们计算训练集中有多少比例的文档属于类别 。令 为训练数据中类别为 的文档数, 为文档总数,则:
为学习 ,我们假设一个特征就是某个词存在于文档词袋中,因此需要估计 :词 在主题为 的所有文档全部词语中所占的比例。先把类别为 的所有文档连接成一篇很大的“类别 ”文本,再用 在这个连接文档中的频率作最大似然估计:
这里的词表 是所有类别中全部词类型的并集,而不只是类别 中的词。
然而,最大似然训练有一个问题。假设我们要估计正面类别下 fantastic 的似然,却没有任何同时包含 fantastic 且被标为正面的训练文档;也许它碰巧以讽刺语气出现在负面类别中。此时,这个特征的概率为零:
但是,朴素贝叶斯会把所有特征似然朴素地相乘,因此任一类别的似然项中只要出现零概率,该类别的概率就会变成零,不管其他证据如何。
最简单的解决方案是第 3 章介绍的加一(Laplace)平滑。语言模型中通常会用更复杂的平滑算法取代 Laplace 平滑,但它在朴素贝叶斯文本分类中很常用:
再次注意,词表 必须是所有类别中全部词类型的并集,而不能只包含某个类别 中的词。(请试着说服自己为什么必须如此;参见本附录末尾的练习。)
如果测试数据中的词根本不在词表里,即它没有在任何类别的任何训练文档中出现,该怎么办?对这种未知词的处理办法是忽略它们:从测试文档中删除,不为其计入任何概率。
最后,有些系统还会完全忽略另一类词:the、a 之类非常高频的停用词。可以按训练集频率对词表排序,把前 10~100 个词项定义为停用词;也可以采用网上已有的停用词表。然后,从训练文档和测试文档中删除停用词的每次出现,就像它们从未出现过一样。不过,在多数文本分类应用中,停用词表并不能提升性能,因此更常见的做法是使用整个词表而不使用停用词表。
图 B.2 给出最终算法。
函数 TRAIN NAIVE BAYES(D, C) 返回 V、log P(c)、log P(w|c)
对每个类别 c ∈ C: # 计算 P(c)
N_doc ← D 中的文档数
N_c ← D 中类别为 c 的文档数
logprior[c] ← log(N_c/N_doc)
V ← D 的词表
bigdoc[c] ← 连接 D 中类别为 c 的所有文档 d
对 V 中每个词 w: # 计算 P(w|c)
count(w,c) ← w 在 bigdoc[c] 中出现的次数
loglikelihood[w,c] ← log((count(w,c)+1)/Σ_{w'∈V}(count(w',c)+1))
返回 logprior、loglikelihood、V
函数 TEST NAIVE BAYES(testdoc, logprior, loglikelihood, C, V) 返回最佳类别 c
对每个类别 c ∈ C:
sum[c] ← logprior[c]
对 testdoc 中每个位置 i:
word ← testdoc[i]
若 word ∈ V:
sum[c] ← sum[c] + loglikelihood[word,c]
返回 argmax_c sum[c]图 B.2 使用加一平滑的朴素贝叶斯算法。若要使用加 平滑,把训练时似然计数中的 +1 改为 。