朴素贝叶斯算法一听就是根据人名来定义的,这个算法包括两部分:第一部分是贝叶斯定理,这个我们在概率论中应该都学习过,下面会简单回顾一下,第二部分是朴素,也就是假设各个特征互相独立,虽然在现实情况中可能各个特征也会有一些相关性,也就是这个假设不完全成立,但是在实际中朴素贝叶斯的效果还是很不错的。
下面简单回顾一下贝叶斯定理,即P(A|B) = [P(B|A) × P(A)] / P(B),这个式子中的P(A|B)是后验概率,它表示在B发生后A的概率,而P(B|A)是似然概率,也就是当前数据的概率,P(A)是先验概率,也就是在观测新数据之前对已有事件的初始概率,P(B)是边际概率,也就是所有可能的假设下观测到数据的总概率。
可以看到在上面的式子中,概率是在动态变化的,这会让一部分人比较困惑,也有很多反对的声音,比如频率学派就认为频率是固定的,他们认为贝叶斯学派的概率的定义是主观的,不够客观,而贝叶斯学派则认为频率学派的定义无法处理一次性事件,现在这两大学派长期共存,在统计学和机器学习中是两大主流思想。
说了这么多理论,来看一下具体的实践,在实际操作时,我们可以使用高斯朴素贝叶斯,也可以用多项式朴素贝叶斯,或者是使用伯努利朴素贝叶斯,我们这里使用高斯朴素贝叶斯来对数据进行三分类,看如下代码:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score
# 构造数据
X, y = make_classification(
n_samples=300, # 样本数量
n_features=2, # 特征数量
n_classes=3, # 类别数量
n_informative=2, # 信息特征数量
n_redundant=0, # 冗余特征数量
n_clusters_per_class=1, # 每个类别的簇数量
random_state=42
)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建并训练朴素贝叶斯分类器
gnb = GaussianNB()
# 训练模型
gnb.fit(X_train, y_train)
# 预测测试集
y_pred = gnb.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"准确率是: {accuracy:.2f}")
# 可视化决策边界
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),
np.arange(y_min, y_max, 0.02))
Z = gnb.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.4)
plt.scatter(X[:, 0], X[:, 1], c=y, alpha=0.8)
plt.title('Naive Bayes Classification')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()
这里我们使用的是高斯朴素贝叶斯,即GaussianNB,这里的NB是Navie Bayes的简写,也就是朴素贝叶斯,对于我们构造的数据,它有两个特征,共计300个样本,3个分类,可以看到它的准确率达到了92%,如下:
对于数据和具体的分类效果则是如下这样的:
朴素贝叶斯还经常用于对文本进行分类,后面有机会再进行相关的介绍和演示。