0. 前言
在前面的几篇博客中,对朴素贝叶斯的理论知识进行了一个学习与总结,接下来希望对sklearn库中的朴素贝叶斯分类器作进一步的学习和说明。
1. 高斯朴素贝叶斯
- 高斯朴素贝叶斯 (GaussianNB)
naive_bayes.GaussianNB(priors=None, var_smoothing=1e-09)
包含两个参数:
① prior:表示类的先验概率(即,没有条件下的P(Y))。若指定,则不根据数据调整;若不指定,则根据数据计算先验。
② var_smoothing:通常使用默认值1e-09。
高斯朴素贝叶斯,是假设P(
x
i
{x_i}
xi|Y)服从高斯分布(即正态分布),估计每个特征下每个类别上的条件概率。
对于每个特征下的取值,高斯朴素贝叶斯有公式如下:
P( x i {x_i} xi|Y) = 1 2 π σ y 2 {1}\over{\sqrt{2\pi\sigma_y^2}} 2πσy21exp(- ( x i − μ y ) 2 2 σ y 2 {(x_i-\mu_y)^2}\over{2\sigma_y^2} 2σy2(xi−μy)2)
σ \sigma σ表示方差; μ \mu μ表示均值
以最大化P( x i {x_i} xi|Y)为目标,高斯朴素贝叶斯会求解出公式中的 σ y \sigma_y σy和 μ y \mu_y μy,之后再代入 x i x_i xi的值,就可以得到一个P( x i {x_i} xi|Y)的概率取值。
调用算法库实现
- 导入相应的包
from sklearn.naive_bayes import GaussianNB # 导入高斯贝叶斯
from sklearn.datasets import load_digits # 导入数据集
from sklearn.model_selection import train_test_split # 用于对数据集划分
- 数据集
此处选择的是手写字体数据集,该数据集包含1797个0-9(每个数字样本的标签分别是0-9中的一个)的手写数字数据,每个数字由8*8(每个数字样本有64个特征)大小的矩阵构成,矩阵中值的范围是0-16,代表颜色的深度。
digits = load_digits()
X = digits.data # 样本
y = digits.target # 标签
print(digits.data.shape) # 样本个数及特征个数
print(numpy.unique(digits.target)) # 类别
输出结果:
(1797, 64) # 1797个样本,每个样本有64个特征值
[0 1 2 3 4 5 6 7 8 9] # 有0-9 十个类别
- 完整代码
from sklearn.naive_bayes import GaussianNB
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
import numpy
# 64个特征,多分类问题,类别是10个
# 1. 加载数据集
digits = load_digits()
X = digits.data # 样本
y = digits.target # 标签
# 2. 划分数据集
X_trainer, X_test, Y_trainer, Y_test = train_test_split(X, y, test_size=0.3)
# 3. 调用GaussianNB
gnb = GaussianNB().fit(X_trainer, Y_trainer)
# 4. 查看预测结果
# 4.1 查看预测精确性
gnb_score = gnb.score(X_test, Y_test) # 返回预测的精确性accuracy
print("Score:", gnb_score)
# 4.1 查看预测结果(对应输出每一个类别下的概率)
gnb_prob = gnb.predict_proba(X_test) # 0-9中概率最大的标签是样本的标签
print("Predict_proba:", gnb_prob)
输出结果:
Score: 0.8388888888888889
Predict_proba: [[7.83962044e-247 1.24834410e-038 4.88551557e-076 ... 0.00000000e+000
1.71525576e-078 4.93278158e-017]
[0.00000000e+000 5.77193722e-030 2.12056943e-092 ... 1.00000000e+000
4.12882737e-079 2.94249055e-046]
[0.00000000e+000 0.00000000e+000 9.99998601e-001 ... 0.00000000e+000
1.93369671e-027 5.40946810e-074]
...
[0.00000000e+000 7.78083591e-034 2.72609234e-107 ... 0.00000000e+000
3.33923163e-036 1.11247866e-132]
[0.00000000e+000 6.24849452e-006 3.75282150e-063 ... 0.00000000e+000
8.87371042e-033 9.99993752e-001]
[1.00000000e+000 4.82157559e-070 3.46377218e-147 ... 0.00000000e+000
2.71845551e-128 1.68767694e-079]]
结果分析:
在前面的博客中,根据分析每一个样本对应每一个类别上的概率总和应该为1,此处可以通过代码验证下:
对第一行(第一个样本)的所有列(每个类别下的概率)求和:
print(gnb_prob[1, :].sum()) # 每一行和为1
输出结果:
1.0