引言
在scikit-learn中,朴素贝叶斯有三种方法:贝努利朴素贝叶斯(BernoulliNB)、高斯朴素贝叶斯(GaussianNB)和多项式朴素贝叶斯(MultinomialNB)。以下一一来介绍。
朴素贝叶斯的原理可以参考我的另一篇<机器学习之朴素贝叶斯>
一、贝努利朴素贝叶斯
贝努利朴素贝叶斯比较适合于符合贝努利分布的数据集,贝努利分布也称为“二项分布”或者“0-1”分布。如果数据集的每个特征都只有 0,1两种数值,那么贝努利贝叶斯的表现不错,但如果是更复杂的数据,则效果一般。下面用make_blob生成样本数未500,分类为5 的数据集。并通过图像来了解下贝努利朴素贝叶斯的工作过程。
import numpy as np
from sklearn.datasets import make_blobs #导入数据集生成工具
from sklearn.model_selection import train_test_split #导入数据集拆分工具
from sklearn.naive_bayes import BernoulliNB #伯努利贝叶斯
import matplotlib.pyplot as plt #导入画图工具
#生成样本数为 500, 分类数为 5 的数据集
X, y = make_blobs(n_samples=500, centers=5, random_state=8)
#拆分训练集和数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=8)
#使用贝努利拟合数据
nb = BernoulliNB()
nb.fit(X_train, y_train)
print('代码运行结果为:')
print('==========================')
print("训练数据得分:{:.2f}".format(nb.score(X_test, y_test)))
#限定横轴和纵轴的最大值
x_min, x_max = X[:,0].min()-0.5, X[:,0].max()+0.5
y_min, y_max = X[:,1].min()-0.5, X[:,1].max()+0.5
#用不同的背景色表示不同的类
xx, yy = np.meshgrid(np.arange(x_min, x_max, .02),
np.arange(y_min, y_max, .02))
z = nb.predict(np.c_[(xx.ravel(), yy.ravel())]).reshape(xx.shape)
plt.pcolormesh(xx, yy, z, cmap=plt.cm.Pastel1)
#将训练集和测试集用散点图表示
plt.scatter(X_train[:,0], X_train[:,1], c=y_train, cmap=plt.cm.cool, edgecolors='k')
plt.scatter(X_test[:,0], X_test[:,1], c=y_test, cmap=plt.cm.cool, edgecolors='k', marker='*')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title('Classifier: BernoulliNB')
plt.show()
执行结果如下:
代码运行结果为:
==========================
训练数据得分:0.54
可以看出贝努利朴素贝叶斯模型十分简单,它分贝在横轴等于0和纵轴等于0的位置画了两条直线,再用这两条直线形成的4个象限对数据进行分类。这是因为代码中使用了贝努利贝叶斯的默认参数 binarize=0.0。
二、高斯朴素贝叶斯
高斯朴素贝叶斯比较适合于符合高斯分布的数据集,或者可以说符合高斯分布时使用的算法。
import numpy as np
from sklearn.datasets import make_blobs #导入数据集生成工具
from sklearn.model_selection import train_test_split #导入数据集拆分工具
from sklearn.naive_bayes import GaussianNB #高斯贝叶斯
import matplotlib.pyplot as plt #导入画图工具
#生成样本数为 500, 分类数为 5 的数据集
X, y = make_blobs(n_samples=500, centers=5, random_state=8)
#拆分训练集和数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=8)
#使用贝努力拟合数据
gnb = GaussianNB()
gnb.fit(X_train, y_train)
print('代码运行结果为:')
print('==========================')
print("训练数据得分:{:.2f}".format(gnb.score(X_test, y_test)))
#限定横轴和纵轴的最大值
x_min, x_max = X[:,0].min()-0.5, X[:,0].max()+0.5
y_min, y_max = X[:,1].min()-0.5, X[:,1].max()+0.5
#用不同的背景色表示不同的类
xx, yy = np.meshgrid(np.arange(x_min, x_max, .02),
np.arange(y_min, y_max, .02))
z = gnb.predict(np.c_[(xx.ravel(), yy.ravel())]).reshape(xx.shape)
plt.pcolormesh(xx, yy, z, cmap=plt.cm.Pastel1)
#将训练集和测试集用散点图表示
plt.scatter(X_train[:,0], X_train[:,1], c=y_train, cmap=plt.cm.cool, edgecolors='k')
plt.scatter(X_test[:,0], X_test[:,1], c=y_test, cmap=plt.cm.cool, edgecolors='k', marker='*')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title('Classifier: BernoulliNB')
plt.show()
执行结果如下:
代码运行结果为:
==========================
训练数据得分:0.97
可以看出相比贝努利朴素贝叶斯模型,高斯贝叶斯的模型得分要好很多,而且分类边界也复杂的多,说明手工生成的数据集的特征基本上符合正态分布。
三、多项式朴素贝叶斯
多项式朴素贝叶斯比较适合于符合多项式分布的数据集。举个栗子,抛硬币是二项式分布,而掷色子是多项式分布,每次的结果是1~6中的一个,投掷n次,每个面朝上的分布情况,就是一个多项式分布。
注意:使用高斯贝叶斯时,输入的X值必须是非负 的,因此需要对数据做预处理。·
import numpy as np
from sklearn.datasets import make_blobs #导入数据集生成工具
from sklearn.model_selection import train_test_split #导入数据集拆分工具
from sklearn.preprocessing import MinMaxScaler #导入数据预处理工具
from sklearn.naive_bayes import MultinomialNB #多项式贝叶斯
import matplotlib.pyplot as plt #导入画图工具
#生成样本数为 500, 分类数为 5 的数据集
X, y = make_blobs(n_samples=500, centers=5, random_state=8)
#拆分训练集和数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=8)
#使用 MinMaxScaler 对数据进行预处理,使得数据全部为非负值
scaler = MinMaxScaler()
scaler.fit(X_train)
X_train_scalerd = scaler.transform(X_train)
X_test_scalerd = scaler.transform(X_test)
#使用贝努力拟合数据
mnb = MultinomialNB()
mnb.fit(X_train_scalerd, y_train)
print('代码运行结果为:')
print('==========================')
print("训练数据得分:{:.2f}".format(mnb.score(X_test_scalerd, y_test)))
#限定横轴和纵轴的最大值
x_min, x_max = X[:,0].min()-0.5, X[:,0].max()+0.5
y_min, y_max = X[:,1].min()-0.5, X[:,1].max()+0.5
#用不同的背景色表示不同的类
xx, yy = np.meshgrid(np.arange(x_min, x_max, .02),
np.arange(y_min, y_max, .02))
z = mnb.predict(np.c_[(xx.ravel(), yy.ravel())]).reshape(xx.shape)
plt.pcolormesh(xx, yy, z, cmap=plt.cm.Pastel1)
#将训练集和测试集用散点图表示
plt.scatter(X_train[:,0], X_train[:,1], c=y_train, cmap=plt.cm.cool, edgecolors='k')
plt.scatter(X_test[:,0], X_test[:,1], c=y_test, cmap=plt.cm.cool, edgecolors='k', marker='*')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title('Classifier: MultinomialNB')
plt.show()
注释:
sklearn.preprocessing.MinMaxScaler 用来转换Vector行的数据集,将每个要素重新缩放到特定范围(通常为[0,1])
执行结果如下:
代码运行结果为:
==========================
训练数据得分:0.32
可以看出多项式朴素贝叶斯模型分类效果差。说明并不适合这个数据集。多项式朴素贝叶斯适合用来对非负离散数值特征进行分类,典型的例子时对转化为向量后的文本数据 进行分类。