写点什么

机器学习算法(二): 基于鸢尾花数据集的朴素贝叶斯 (Naive Bayes) 预测分类

作者:汀丶
  • 2023-03-23
    浙江
  • 本文字数:4467 字

    阅读完需:约 15 分钟

机器学习算法(二): 基于鸢尾花数据集的朴素贝叶斯(Naive Bayes)预测分类


1. 实验室介绍

1.1 实验环境

1. python3.72. numpy >= '1.16.4'3. sklearn >= '0.23.1'
复制代码

1.2 朴素贝叶斯的介绍

朴素贝叶斯算法(Naive Bayes, NB) 是应用最为广泛的分类算法之一。它是基于贝叶斯定义和特征条件独立假设的分类器方法。由于朴素贝叶斯法基于贝叶斯公式计算得到,有着坚实的数学基础,以及稳定的分类效率。NB 模型所需估计的参数很少,对缺失数据不太敏感,算法也比较简单。当年的垃圾邮件分类都是基于朴素贝叶斯分类器识别的。


什么是条件概率,我们从一个摸球的例子来理解。我们有两个桶:灰色桶和绿色桶,一共有 7 个小球,4 个蓝色 3 个紫色,分布如下图:


<img src="http://tianchi-media.oss-cn-beijing.aliyuncs.com/DSW/2NaiveBayes/ball_ab.png" />


从这 7 个球中,随机选择 1 个球是紫色的概率 p 是多少?选择过程如下:


  1. 先选择桶

  2. 再从选择的桶中选择一个球


p(球=紫色) \=p(选择灰桶) \cdot p(从灰桶中选择紫色) + p(选择绿桶) \cdot p(从灰桶中选择紫色) \=\frac{1}{2} \cdot \frac{2}{4} + \frac{1}{2} \cdot \frac{1}{2}


上述我们选择小球的过程就是条件概率的过程,在选择桶的颜色的情况下是紫色的概率,另一种计算条件概率的方法是贝叶斯准则。


贝叶斯公式是英国数学家提出的一个数据公式:



p(A,B):表示事件 A 和事件 B 同时发生的概率。


p(B):表示事件 B 发生的概率,叫做先验概率;p(A):表示事件 A 发生的概率。


p(A|B):表示当事件 B 发生的条件下,事件 A 发生的概率叫做后验概率。


p(B|A):表示当事件 A 发生的条件下,事件 B 发生的概率。


我们用一句话理解贝叶斯:世间很多事都存在某种联系,假设事件 A 和事件 B。人们常常使用已经发生的某个事件去推断我们想要知道的之间的概率。例如,医生在确诊的时候,会根据病人的舌苔、心跳等来判断病人得了什么病。对病人来说,只会关注得了什么病,医生会通道已经发生的事件来确诊具体的情况。这里就用到了贝叶斯思想,A 是已经发生的病人症状,在 A 发生的条件下是 B_i 的概率。

1.3 朴素贝叶斯的应用

朴素贝叶斯算法假设所有特征的出现相互独立互不影响,每一特征同等重要,又因为其简单,而且具有很好的可解释性一般。相对于其他精心设计的更复杂的分类算法,朴素贝叶斯分类算法是学习效率和分类效果较好的分类器之一。朴素贝叶斯算法一般应用在文本分类,垃圾邮件的分类,信用评估,钓鱼网站检测等。

2. 实验室手册

2.1 学习目标

  1. 掌握贝叶斯公式

  2. 结合两个实例了解贝朴素叶斯的参数估计

  3. 掌握贝叶斯估计

2.2 代码流程

  • Part 1. 莺尾花数据集--贝叶斯分类

  • Step1: 库函数导入

  • Step2: 数据导入 &分析

  • Step3: 模型训练

  • Step4: 模型预测

  • Step5: 原理简析

  • Part 2. 模拟离散数据集--贝叶斯分类

  • Step1: 库函数导入

  • Step2: 数据导入 &分析

  • Step3: 模型训练 &可视化

  • Step4: 原理简析

2.3 算法实战

莺尾花数据集--贝叶斯分类

Step1: 库函数导入


import warningswarnings.filterwarnings('ignore')import numpy as np# 加载莺尾花数据集from sklearn import datasets# 导入高斯朴素贝叶斯分类器from sklearn.naive_bayes import GaussianNBfrom sklearn.model_selection import train_test_split
复制代码


Step2: 数据导入 &分析


X, y = datasets.load_iris(return_X_y=True)X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
复制代码


我们需要计算两个概率分别是:条件概率:和类目的先验概率:


通过分析发现训练数据是数值类型的数据,这里假设每个特征服从高斯分布,因此我们选择高斯朴素贝叶斯来进行分类计算。


Step3: 模型训练


# 使用高斯朴素贝叶斯进行计算clf = GaussianNB(var_smoothing=1e-8)clf.fit(X_train, y_train)
复制代码


Step4: 模型预测


# 评估y_pred = clf.predict(X_test)acc = np.sum(y_test == y_pred) / X_test.shape[0]print("Test Acc : %.3f" % acc)
# 预测y_proba = clf.predict_proba(X_test[:1])print(clf.predict(X_test[:1]))print("预计的概率值:", y_proba)
复制代码


Test Acc : 0.967 [2] 预计的概率值: [[1.63542393e-232 2.18880483e-0069.99997811e-001]]


Step5: 原理简析高斯朴素贝叶斯假设每个特征都服从高斯分布,我们把一个随机变量 X 服从数学期望为μ,方差为σ^2 的数据分布称为高斯分布。对于每个特征我们一般使用平均值来估计μ和使用所有特征的方差估计σ^2。



从上述例子中的预测结果中,我们可以看到类别 2 对应的后验概率值最大,所以我们认为类目 2 是最优的结果。

模拟离散数据集--贝叶斯分类

Step1: 库函数导入+ Step2: 数据导入 &分析+ Step3: 模型训练 &可视化+ Step4: 原理简析


import randomimport numpy as np# 使用基于类目特征的朴素贝叶斯from sklearn.naive_bayes import CategoricalNBfrom sklearn.model_selection import train_test_split
复制代码


Step2: 数据导入 &分析


# 模拟数据rng = np.random.RandomState(1)# 随机生成600个100维的数据,每一维的特征都是[0, 4]之前的整数X = rng.randint(5, size=(600, 100))y = np.array([1, 2, 3, 4, 5, 6] * 100)data = np.c_[X, y]# X和y进行整体打散random.shuffle(data)X = data[:,:-1]y = data[:, -1]X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
复制代码


所有的数据特征都是离散特征,我们引入基于离散特征的朴素贝叶斯分类器。


Step3: 模型训练 &预测


clf = CategoricalNB(alpha=1)clf.fit(X_train, y_train)acc = clf.score(X_test, y_test)print("Test Acc : %.3f" % acc)
复制代码


Test Acc : 0.683


# 随机数据测试,分析预测结果,贝叶斯会选择概率最大的预测结果# 比如这里的预测结果是6,6对应的概率最大,由于我们是随机数据# 读者运行的时候,可能会出现不一样的结果。x = rng.randint(5, size=(1, 100))print(clf.predict_proba(x))print(clf.predict(x))
复制代码


[[3.48859652e-04 4.34747491e-04 2.23077189e-03 9.90226387e-01  5.98248900e-03 7.76745425e-04]]
复制代码

2.4 原理简析

2.4.1 结果分析

可以看到测试的数据的结果,贝叶斯会选择概率最大的预测结果,比如这里的预测结果是 6,6 对应的概率最大,由于我们是随机数据,读者运行的时候,可能会出现不一样的结果。


这里的测试数据的准确率没有任何意义,因为数据是随机生成的,不一定具有贝叶斯先验性,这里只是作为一个列子引导大家如何使用。


alpha=1 这个参数表示什么?


我们知道贝叶斯法一定要计算两个概率:条件概率:和类目的先验概率:


对于离散特征:



我们可以看出就是对每一个变量的多加了一个频数 alpha。当 alphaλ=0 时,就是极大似然估计。通常取值 alpha=1,这就是拉普拉斯平滑(Laplace smoothing),这有叫做贝叶斯估计,主要是因为如果使用极大似然估计,如果某个特征值在训练数据中没有出现,这时候会出现概率为 0 的情况,导致整个估计都为 0,因为引入贝叶斯估计。


其中:


:表示第 j 个特征的个数。


:表示第 i 个样本的第 j 维元素。


:第 i 个样本的 label。

2.4.2 朴素贝叶斯算法

朴素贝叶斯法 = 贝叶斯定理 + 特征条件独立。


输入空间是 n 维向量集合,输出空间. 所有的 X 和 y 都是对应空间上的随机变量. 是 X 和 Y 的联合概率分别. 训练数据集(由独立同分布产生):


计算测试数据 x 的列表,我们需要依次计算,取概率最大的值,就是 x 对应的分类。


我们一般这样解释,当给定的条件下,的概率,这就是条件概率. 这就简单了,我们只需要每个的 x,计算其对应的的概率,选择最大的概率作为这个 x 的类别进行了.


通过贝叶斯公式进行变形,得到预测的概率计算公式:



我们只需要计算以下两个概率即可,又由于朴素贝叶斯假设条件独立,我们可以单独计算每个特征的条件概率:和类目的先验概率:。为了更好的理解这个公式,看下图解释:


其中:



当涉及到多个条件时,朴素贝叶斯有一个提前的假设,我们称之为 条件独立性假设(或者 简单假设:Naive):公式如下



这个公式是朴素贝叶斯的基础假设,即各个条件概率是相互独立的,A 不影响 B,B 不影响 A。而对这里来说,假设


P(X=x|Y=c_k) \=P(X^{(1)}=x^{(1)},X^{(2)}=x^{(2)},...,X^{(n)}=x^{(n)}|Y=c_k) \=\prod_{i=1}^{n} P(x_i | y)


由此原式可以等价为:



我们为了选择后验概率最大的结果,进行概率的比较,由于分母一致,这里直接去掉分母,得到最后的计算公式。



<img src="http://tianchi-media.oss-cn-beijing.aliyuncs.com/DSW/2NaiveBayes/bayes2.png" />


我们来看一个实例,更好的理解贝叶斯的计算过程,根据天气和是否是周末预测一个人是否会出门。



根据上述数据,为了更好的理解计算过程,我们给出几个计算公式:


a. 当出门的条件下,X_1 是天气不好的概率:



b. 出门的概率



c. X_1 天气不好的概率、



d. 在 X_1 天气不好的情况下,出门的概率:


f. 在 X_1 天气不好的情况下,不出门的概率:


2.4.3 朴素贝叶斯的优缺点

优点:朴素贝叶斯算法主要基于经典的贝叶斯公式进行推倒,具有很好的数学原理。而且在数据量很小的时候表现良好,数据量很大的时候也可以进行增量计算。由于朴素贝叶斯使用先验概率估计后验概率具有很好的模型的可解释性。


缺点:朴素贝叶斯模型与其他分类方法相比具有最小的理论误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型给定输出类别的情况下,假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。而在属性相关性较小时,朴素贝叶斯性能最为良好。对于这一点,有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进,例如为了计算量不至于太大,我们假定每个属性只依赖另外的一个。解决特征之间的相关性,我们还可以使用数据降维(PCA)的方法,去除特征相关性,再进行朴素贝叶斯计算。


项目链接参考:https://www.heywhale.com/home/column/64141d6b1c8c8b518ba97dcc

发布于: 刚刚阅读数: 5
用户头像

汀丶

关注

本博客将不定期更新关于NLP等领域相关知识 2022-01-06 加入

本博客将不定期更新关于机器学习、强化学习、数据挖掘以及NLP等领域相关知识,以及分享自己学习到的知识技能,感谢大家关注!

评论

发布
暂无评论
机器学习算法(二): 基于鸢尾花数据集的朴素贝叶斯(Naive Bayes)预测分类_数据挖掘_汀丶_InfoQ写作社区