scikits learn 和 nltk:朴素贝叶斯分类器性能差异很大

Posted

技术标签:

【中文标题】scikits learn 和 nltk:朴素贝叶斯分类器性能差异很大【英文标题】:scikits learn and nltk: Naive Bayes classifier performance highly different 【发布时间】:2012-05-11 13:04:24 【问题描述】:

我正在比较两个朴素贝叶斯分类器:一个 from NLTK 和一个 from scikit-learn。我正在处理一个多类分类问题(3 类:正(1)、负(-1)和中性(0))。

没有执行任何特征选择(即使用所有可用特征),并使用 70,000 个实例的训练数据集(噪声标记,实例分布为 17% 正、4% 负和 78% 中性),我训练两个分类器,第一个是 nltk.NaiveBayesClassifier,第二个是 sklearn.naive_bayes.MultinomialNB(带有fit_prior=True)。

训练后,我在包含 30,000 个实例的测试集上评估了分类器,得到以下结果:

**NLTK's NaiveBayes**
accuracy: 0.568740
class: 1
     precision: 0.331229
     recall: 0.331565
     F-Measure: 0.331355
class: -1
     precision: 0.079253 
     recall: 0.446331 
     F-Measure: 0.134596 
class: 0
     precision: 0.849842 
     recall: 0.628126 
     F-Measure: 0.722347 


**Scikit's MultinomialNB (with fit_prior=True)**
accuracy: 0.834670
class: 1
     precision: 0.400247
     recall: 0.125359
     F-Measure: 0.190917
class: -1
     precision: 0.330836
     recall: 0.012441
     F-Measure: 0.023939
class: 0
     precision: 0.852997
     recall: 0.973406
     F-Measure: 0.909191

**Scikit's MultinomialNB (with fit_prior=False)**
accuracy: 0.834680
class: 1
     precision: 0.400380
     recall: 0.125361
     F-Measure: 0.190934
class: -1
     precision: 0.330836
     recall: 0.012441
     F-Measure: 0.023939
class: 0
     precision: 0.852998
     recall: 0.973418
     F-Measure: 0.909197

我注意到,虽然 Scikit 的分类器具有更好的整体准确度和精确度,但与 NLTK 相比,它的召回率非常低,至少就我的数据而言。考虑到它们可能(几乎)是相同的分类器,这不是很奇怪吗?

【问题讨论】:

有什么特点?你也试过BernoulliNB吗?这应该更接近于 NLTK 朴素贝叶斯。 感谢您的回复。如果它们存在于文档中,则特征是值为 1 的单词(布尔值)。 scikits BernoulliNB 的结果非常接近 MultinomialNB:accuracy: 0.834680 class: 1 precision: 0.400380 recall: 0.125361 F-Measure: 0.190934 class: -1 precision: 0.330836 recall: 0.012441 F-Measure: 0.023939 class: 0 precision: 0.852998 recall: 0.973418 F-Measure: 0.909197 我在文档中唯一能看到的是 NLTK 的 NB 分类器显然没有进行平滑处理。不过,我不认为这会造成很大的不同...... 【参考方案1】:

两个库中类权重的默认行为是否相同?稀有类(-1)的精度差异看起来可能是原因......

【讨论】:

NLTK 中的朴素贝叶斯考虑了先验标签概率,并且(我认为)Scikits 在使用 with fit_prior=True 参数时也是如此...... 我的(可能是错误的)理解是 fit_prior=True 将使用实际的类权重,例如,将所有负样本(样本的 4%)分配给中性类只会导致-4% 的准确率(这似乎是它正在做的事情)。尝试使用 fit_prior=False 运行它。 谢谢。我尝试使用 fit_prior=False 运行它,令人惊讶的是它给出了几乎相同的结果(我更新了主帖)【参考方案2】:

朴素贝叶斯分类器通常是指在假定为独立的二元特征上的贝叶斯分类器。这就是NLTK's Naive Bayes classifier 实现的。对应的scikit分类器为BernoulliNB分类器。

对布尔值特征的限制实际上不是必需的, 它只是最简单的实现。 可以为来自任何参数分布的(假设的)独立特征定义朴素贝叶斯分类器。

MultinomialNB 用于具有整数值输入特征的数据,这些特征假定为多项式分布。

Sckit 还有GaussianNB,用于假定独立高斯分布的连续值特征。

【讨论】:

以上是关于scikits learn 和 nltk:朴素贝叶斯分类器性能差异很大的主要内容,如果未能解决你的问题,请参考以下文章

scikit-learn 朴素贝叶斯类库使用小结

SciKit-learn - 训练高斯朴素贝叶斯分类器

处理 scikit learn 的朴素贝叶斯看不见的特征

如何为 scikit-learn 的朴素贝叶斯指定先验概率

保存和加载测试以另一种方法对 NLTK 中的朴素贝叶斯分类器进行分类

Scikit-Learn 朴素贝叶斯分类丨数析学院