sk-learn机器学习之朴素贝叶斯
朴素贝叶斯概述
前面我们学习了很多用于分类的算法,比如决策树,逻辑回归等,但是他们并不是真正意义上的概率算法,而朴素贝叶斯是一种直接衡量标签和特征之间的概率关系的监督算法,它不仅可以用于回归也可以用于分类(大多数时候用于分类)
朴素贝叶斯的原理(涉及概率论)
首先我们需要理解两个概念(这里以两个随机变量X,Y作为例子):
- 联合概率:X取到特定的值,Y取到特定的值,两个事件同时发生的概率
- 条件概率:X取到特定的值为前提,Y取到特定的值的概率
在概率论中我们可以证明:
任意两个事件的联合概率等于着两个事件任意条件概率 * 这个事情本身的概率
所以我们可以得到贝叶斯理论等式
这个式子表示:
在X发生的前提下Y发生的概率 =
在Y发生的前提下X发生的概率 * Y单独发生的概率 / X单独发生的概率
这就是贝叶斯算法的根源理论
为什么叫朴素贝叶斯
为什么我们说它是朴素的呢?——因为我们假设特征之间是条件独立的,不会相互影响的
我们再回到朴素贝叶斯,我们可以知道朴素贝叶斯是之间从样本数据集中直接计算概率的——也就是说朴素贝叶斯是一个不需要建模的有监督的算法。
之前我们学习的很多算法,都是需要从训练集中学习,获取足够多的信息来建立模型,然后使用测试集来预测模型的好坏。而朴素贝叶斯不需要。
注意!!!朴素贝叶斯也是有缺点的
- 如果测试集中出现了训练集中没有出现过的概率组合——也就是特征组合,这时候会出现概率为0的情况——显然这种预测是不合理的
- 现实种大多数标签是连续性变量,而连续性变量的概率就不是直接那样本特征计算那么简单了,我们需要绘制概率密度曲线通过积分的方式来计算和估计概率
常见的三种朴素贝叶斯
高斯朴素贝叶斯
我们可以看看它的原型:
sklearn.naive_bayes.GaussianNB(priors=None, var_something=1e-09)
- prior : 先验概率
- var_something : 估计方差时,追求稳定性,将所有特征中的最大方差按比例添加到估计的方差中,这个比例由var_something控制
一般来说这两个参数都不需要填写
这也意味着我们的高斯朴素贝叶斯几乎没有什么可以优化的地方
多项式朴素贝叶斯
首先是原型:
sklearn.naive_bays.MultinomialNB(alpha=1.0, fit_prior=True, class_prior=None)
三个参数
- alpha:系数,一般使用默认的1, 调优时,选择稍大或稍小于1的数
- fit_prior:先验概率,false则所有样本输出都有相同的先验概率,true则可以使用class_prior输入先验概率
- class_prior: 输入先验概率,不输入则让多项式朴素贝叶斯自己从训练集样本中计算先验概率
伯努利朴素贝叶斯
原型:
sklearn.naive_bays.BernoulliNb(
alpha=1.0,
binarize= .0,
fit_prior=True,
class_prior=None)
跟多项式一样,多了一个参数
binarize : 二值化的样本特征阈值
朴素贝叶斯实战
下面我们使用三种朴素贝叶斯来看看效果吧
from sklearn.naive_bayes import GaussianNB
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.naive_bayes import BernoulliNB
digits = load_digits()
x = digits.data
y = digits.target
# 划分测试集和训练集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=420)
# 导入模型训练
pred1 = GaussianNB().fit(x_train, y_train)
pred2 = MultinomialNB().fit(x_train, y_train)
pred3 = BernoulliNB().fit(x_train, y_train)
# 查看分数
score1 = pred1.score(x_test, y_test)
score2 = pred2.score(x_test, y_test)
score3 = pred3.score(x_test, y_test)
print(score1)
print(score2)
print(score3)
# 查看预测结果
y_pred = pred1.predict(x_test)
# 查看预测的概率结果
prob = pred1.predict_proba(x_test)
输出三个朴素贝叶斯的准确率:
0.8592592592592593
0.9
0.8666666666666667
可以看出多项式贝叶斯的性能更优越些
混淆矩阵
这里我们提一下混淆矩阵——用来总结分类算法性能的技术
当每个类中的样本数量不等,数据集中有两个以上的类,则仅用分类准确率作为评判标准容易产生误导,所有我们需要混淆矩阵
为什么需要混淆矩阵
我们知道分类准确率是预测正确的样本数与总样本数的比值,但它会隐藏一些我们需要的细节
比如:我们的类别有很多个的时候,我们不知道哪些类被预测的好,哪些类预测的不好
而使用混淆矩阵可以进一步区分这些细节
混淆矩阵的用法
混淆矩阵是对分类问题的预测结果的总结。使用计数值汇总正确和不正确预测的数量,并按每个类进行细分。==混淆矩阵显示了分类模型在进行预测时会对哪一部分产生混淆。==所以我们可以了解那些错误预测在那里发生
from sklearn.metrics import confusion_matrix as CM
print(CM(y_test, y_pred))
输出结果:
[[47 0 0 0 0 0 0 1 0 0]
[ 0 46 2 0 0 0 0 3 6 2]
[ 0 2 35 0 0 0 1 0 16 0]
[ 0 0 1 40 0 1 0 3 4 0]
[ 0 0 1 0 39 0 1 4 0 0]
[ 0 0 0 2 0 58 1 1 1 0]
[ 0 0 1 0 0 1 49 0 0 0]
[ 0 0 0 0 0 0 0 54 0 0]
[ 0 3 0 1 0 0 0 2 55 0]
[ 1 1 0 1 2 0 0 3 7 41]]
可以看到在对角线上是预测正确的数目,还是很多的
感谢耐心阅读!!!