拜读的是这本《Python机器学习基础教程》,本文选自第2章“监督学习”第3节“监督学习算法中的朴素贝叶斯分类器。
本书全部代码:https://github.com/amueller/introduction_to_ml_with_python
朴素贝叶斯分类器是与上一节介绍的线性模型非常相似的一种分类器,但它的训练速度往往更快。然而高效率的代价是:朴素贝叶斯模型的泛化能力要比线性分类器(如LogisticRegression 和 LinearSVC)稍差。
朴素贝叶斯模型高效的原因:通过单独查看每个特征来学习参数,并从每个特征中收集简单的类别统计数据。
scikit-learn 中实现了三种朴素贝叶斯分类器:GaussianNB、BernoulliNB 和 MultinomialNB。
BernoulliNB分类器计算每个类别中每个特征不为 0 的元素个数。以下例子用于说明:
import numpy as np
X=np.array([[0,1,0,1],
[1,0,1,1],
[0,0,0,1],
[1,0,1,0]])
y=np.array([0,1,0,1])
这里我们有 4 个数据点,每个点有 4 个二分类特征。一共有两个类别:0 和 1。对于类别 0(第 1、3 个数据点),第一个特征有 2 个为零、0 个不为零,第二个特征有 1 个为零、1 个不为零,以此类推。然后对类别 1 中的数据点计算相同的计数。计算每个类别中的非零元素个数,大体上看起来像这样:
>>> counts={}
>>> for label in np.unique(y):
counts[label]=X[y==label].sum(axis=0)
>>> print("Featurecounts:\n",counts)
Featurecounts:
{0: array([0, 1, 0, 2]), 1: array([2, 0, 2, 1])}
另外两种朴素贝叶斯模型(MultinomialNB 和 GaussianNB)计算的统计数据类型略有不同。
MultinomialNB计算每个类别中每个特征的平均值,而 GaussianNB 会保存每个类别中每个特征的平均值和标准差。
要想做出预测,需要将数据点与每个类别的统计数据进行比较,并将最匹配的类别作为预测结果。
MultinomialNB和BernoulliNB预测公式的形式都与线性模型完全相同(见上一节)。
朴素贝叶斯模型 coef_ 的含义与线性模型稍有不同,因为 coef_不同于 w。
MultinomialNB 和 BernoulliNB 都只有一个参数 alpha,用于控制模型复杂度。alpha 的工作原理是,算法向数据中添加 alpha 这么多的虚拟数据点,这些点对所有特征都取正值。这可以将统计数据“平滑化”(smoothing)。alpha 越大,平滑化越强,模型复杂度就越低。
算法性能对 alpha 值的鲁棒性相对较好,也就是说,alpha 值对模型性能并不重要。但调整这个参数通常都会使精度略有提高。
GaussianNB 主要用于高维数据,而另外两种朴素贝叶斯模型则广泛用于稀疏计数数据,比如文本。MultinomialNB 的性能通常要优于 BernoulliNB,特别是在包含很多非零特征的数据集(即大型文档)上。
朴素贝叶斯模型的许多优点和缺点都与线性模型相同。它的训练和预测速度都很快,训练过程也很容易理解。该模型对高维稀疏数据的效果很好,对参数的鲁棒性也相对较好。朴素贝叶斯模型是很好的基准模型,常用于非常大的数据集,在这些数据集上即使训练线性模型可能也要花费大量时间。