引言
和撰写博文[1]的缘由一样,本文是想要在所创设的专栏[2]里把所谓的十大机器学习算法[3]全部过一遍。 朴素贝叶斯算法是传统机器学习里的一种可以被用来进行分类的算法,本文将对其原理进行说明,并基于原理给出一个基于该算法的分类实践。
Blog
2024.11.16 博文第一次写作
目录
引言
目录
一、朴素贝叶斯算法相关概念
1.1 贝叶斯定理
1.2 朴素贝叶斯算法
二、基于朴素贝叶斯算法的分类处理流程
三、基于朴素贝叶斯算法的分类实践
3.1 数据集简介
3.2 分类实践与讨论
3.3 本章小结
四、总结
五、参考资料
六、数据与代码
一、朴素贝叶斯算法相关概念
1.1 贝叶斯定理
朴素贝叶斯算法(Naïve Bayes algorithm)是一种基于贝叶斯定理的概率统计分类方法,理解了贝叶斯定理也就知道了朴素贝叶斯算法。这里先对贝叶斯定理做个介绍:贝叶斯定理描述了两个事件之间的条件概率关系,简单来说,当我们不能准确知道事物本质(某个事件发生的概率)时,可以根据与事物特定本质相关的事件出现的多少去判断该事物的本质。用公式来表述就是:
(1-1)
上式表达的含义就是:在事件b发生的前提下,事件a发生的概率等于:事件a发生的前提下,事件b发生的概率 乘以 事件a发生的概率,然后除以事件b发生的概率。 可能比较拗口,我们举例来说明(我这里用了参考资料[4]中的例子,读者可以参考该博文对贝叶斯相关理论有更深刻的理解):
问:现分别有 A、B 两个容器,在容器 A 里分别有 7 个红球和 3 个白球,在容器 B 里有 1 个红球和 9 个白球,现已知从这两个容器里任意抽出了一个球,且是红球,问这个红球是来自容器 A 的概率是多少?
答:这个问题就是很明显的:在某一事件发生的前提下,求另一事件发生的概率是多少。 于是我们可以考虑用贝叶斯定理来解答,为了能用上公式(1-1),我们需要先将a事件和b事件定义好。
而由上述问题我们可以很自然地进行如下定义: 事件b为:抽出红球; 事件a为:选中容器A。 则上述问题对应到式(1-1)就是:P(a|b) = 在选中容器A的前提下,抽出红球的概率 P(b|a) * 选中容器A的概率 P(a) / 抽出红球的概率 P(b)。 从给出的数据来看,在选中容器A的前提下,抽出红球的概率为7/(7+3) = 7/10; 选中容器A的概率为1/2; 抽出红球的概率为(7+1)/(7+3+1+9) = 8/20; 则此时:
(1-2)
有关贝叶斯定理的证明,不在本文的讨论范围,读者可以自行搜索一些资料进行理解。
1.2 朴素贝叶斯算法
如前所述,朴素贝叶斯算法是一种基于贝叶斯定理的概率统计分类方法。有了贝叶斯定理后,如何将之用到分类上?贝叶斯定理输出的是概率值,如果有本专栏[2]之前所探讨过的一些分类算法和实践的基础,我们可以很敏感地意识到有了概率值我们就可以用来做分类。 将上一节的例子拓展一下:比如我们可以把两个容器拓展等效为两个类别(两种瓶子),红球和白球的数量就是样本的特征,(其中一个类别下,其各个样本(样本就是具体的某个瓶子)里红球的数量多,而另一个类别下白球的数量多)。 那么当我们拿到一个未知类别的瓶子时,我们就可以基于其中红球和白球的数量来推得该瓶子属于哪类瓶子。 可能这个例子不是很合适,如果还有问题的话,读者可以从[4]中有关听音判别葡萄酒好/坏的例子中获得更深入的理解。
总之,贝叶斯定理是可以帮助我们进行分类的。 那么,为什么放到分类应用里,名字就成为了朴素贝叶斯?:朴素贝叶斯是一种基于贝叶斯定理与特征条件独立假设的分类方法。它之所以被称为“朴素”,是因为它假设了输入特征之间的条件独立性,即一个特征的出现概率与其他特征无关。(尽管这个假设在现实中很少成立,但朴素贝叶斯分类器在许多实际应用中仍然表现出了出色的性能:比如文本分类、邮件分类等)。样本各特征之间分布独立是朴素贝叶斯应用于分类的基本前提之一!
二、基于朴素贝叶斯算法的分类处理流程
为了实践朴素贝叶斯分类算法,我们先不去考虑样本各特征之间是否相互独立,(我们针对的就是各特征之间相互独立的样本)。
在前述理论的指导下,若要进行分类实践,我们需要做好两点: 一是将问题拆解清楚:事件a是什么?事件b是什么? 二是求得几个概率值:P(a)、P(b)、P(b|a)。 和我们在专栏[2]之前的博文中阐述过的各类典型的机器学习问题/算法相同的是:朴素贝叶斯算法下我们也需要有训练集、测试集,我们需要基于训练集来获得前述几个概率值,测试集则可以用来评估分类的准确率;而和之前讨论过的比如logistic、softmax等算法不同的是:我们不需要用到分类模型、损失函数、优化算法这几个机器学习中的典型概念来实践这里的分类。
所以从这里我们就可以意识到该算法的优点:逻辑简单,计算复杂度低(不需要复杂的迭代优化),易于实现、对数据缺失不敏感(在大样本下,小部分的数据丢失不会影响我们去求解概率分布)、此外其分类效果其实很好(特别在文本分类、垃圾邮件检测等方面)。 该算法最大的缺点在于:我们需要假设特征之间相互独立,但是这在现实中往往很难成立,当特征之间存在相关性时,该算法的性能可能会受到影响。
本文我暂不去深究该算法的一些更底层的东西,暂时只面向两个问题:算法原理是什么,以及如何基于该算法进行具体的分类实践。那么在前文的论述下,基于该算法进行分类的典型处理流程可以归纳如下:
图2.1 基于朴素贝叶斯算法进行分类的典型处理流程
三、基于朴素贝叶斯算法的分类实践
在前述理论和流程的指导下,本章我们进行分类实践。所选用的数据集是我在之前的博文中常用的Iris鸢尾花卉数据集[5]。
3.1 数据集简介
Iris鸢尾花卉数据集是UCI数据库里面典型的可用以分类实践的数据集,该数据集读者可以从[5]中下载,同时我也和代码一并上传到了后文的链接中,我在本专栏[2]之前的聚类和分类博文中使用过多次该数据集,有关此数据集比较细致的介绍,读者可以参考我博文[6]中2.1节的内容。 总之,该数据集一共有150个样本,分为三类(不妨将之编号为类别0、1、2),每类有50个样本,每个样本有4个特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度)。
3.2 分类实践与讨论
我这里按照图2.1的流程来一一实践:
【问题拆解】:这里的分类问题,本质上就是:对于某一未知类别的样本,在给定其特征数值的情况下,该样本所属哪个类别? 该数据集有4个特征值,3种类别,我们需要构建多个事件:
表3.1 问题拆解 --- 事件设计列表
事件 | 描述 |
事件b1 | 花萼长度等于值x1 |
事件b2 | 花萼宽度等于值x2 |
事件b3 | 花瓣长度等于值x3 |
事件b4 | 花瓣宽度等于值x4 |
事件a1 | 该样本属于类别0 |
事件a2 | 该样本属于类别1 |
事件a3 | 该样本属于类别2 |
因为该数据集有四个特征,【我们可以只使用其中一个特征或两个特征或三个特征或者四个特征全部使用,我这里使用了全部四个特征】,认为四个特征之间相互独立。 其实判断样本的所属类别,理论上只需要用其一个特征即可,对应到上面的表格,如果只用花萼长度这个特征,我们可以求出:P(a1|b1)、P(a2|b1)、P(a3|b1),然后取其中的最大值对应的类别为样本的所属类别即可。 本章的实践中使用四个特征,是通过求得各个特征下所属各类别的概率和(或者归一化后的概率和) 来判断样本所属类别,比如,样本所属类别1的概率为:
(3-1)
对于其它几个类别,以上式类推即可。(上面的概率值是会大于1的,为更显得标准些,我们可以在求得样本所属各类别的概率后做归一化处理,不过不管怎样 取最终概率值最大的为该样本的所属类别即可)。
【数据预处理】 我从每个类别的50组样本中,分别随机地取40个样本作为训练集,剩余10个作为测试集。 和以往所理解的训练集有所不同的是,因为我们后面是要分别求每个类别下特征的数值取某个值的概率,所以当计算每个类别下特征值的概率时,训练集具有排它性:我们实际上此时是要构造分别所属3个类别的3个训练集,不过测试集是共用的。
表3.2 训练集和测试集分配情况列表
数据集 | 说明 |
训练集1 | 样本都属于类别0,共40个样本 |
训练集2 | 样本都属于类别1,共40个样本 |
训练集3 | 样本都属于类别2,共40个样本 |
训练集0(综合) | 样本来源于三个类别,每个类别40个样本,共120个样本 |
测试集 | 样本来源于3个类别,每个类别10个样本,共30个样本 |
【概率计算】我们需要基于训练集计算:P(bi|aj)、P(aj)、P(bi),其中:i要取1、2、3、4,j要取1、2、3。 我这里以P(a1)、P(b1)、P(b1|a1)以及待求解的P(a1|b1)为例,分别阐述如何求解这几个概率值。
P(a1)是指:训练集0中样本属于类别0的概率,这个直接就可以得到:训练集0中,每个类别的数量都是占比1/3。 那么P(a1) = P(a2) = P(a3) = 1/3;
P(b1)是指:训练集0中花萼长度等于某值X的概率,虽然我们的训练数据集0中只有120个样本(是离散的),但是花萼长度理应是一个连续变量!此时求其概率我们需要用概率密度值来估测特定长度X下的概率。(有关概率密度我在之前的博文[7]中有过介绍),这里我假定花萼长度值是一个符合高斯分布的变量【这个假设不算是很准确,是为了方便起见才这样做,事实上也可以用拟合的方法拟合出对应的分布再求解概率值】,我们可以利用其均值μ和方差σ2,然后基于高斯分布的概率密度公式:
(3-2)
来近似估测概率值。 我用Matlab自带的histfit函数画了一下测试集0中,花萼长度的直方图分布以及正态分布曲线拟合的情况:
图3.1 训练集0中花萼长度的分布情况
还算凑合吧…,(读者可以基于后文提供的代码画出别的特征的分布)。 求出其均值为:5.89,其方差值为:0.7096。 那么如果X取值为4.5,则其概率为:
P(b1|a1)是指:类别0中花萼长度等于某值X的概率,同上面的分析,只是这里我们仅研究训练数据集1中花萼长度的概率密度分布,处理的方法类似,求得其均值和方差后,再带入公式(3-2)进行求解。 我这里也画一下类别0对应的训练集1中花萼长度的分布情况:
图3.2 训练集1中花萼长度的分布情况
也还算凑合吧…,(读者可以基于后文提供的代码画出别的特征的分布)。 求出其均值为:5.0375,其方差值为:0.1278。 那么如果X取值为4.5,则其概率为:
P(a1|b1)是指:在花萼长度取值为某值X的前提下,该样本属于类别0的概率值,我们还是将X取值为4.5,那么依据贝叶斯公式(1-1)以及我们上面已经计算得到的概率值,可以得到:
说明当花萼长度取值为4.5时,该样本有98.96%的概率属于类别0.
【分类测试/结果】有了上面的基础,对于每个样本,我们分别分析其每个特征取值的情况下该样本所属各个类别的概率,然后求概率之和,概率最大值对应的类别就被认为是该样本的所属类别。【处理过程大多为重复性的、比较繁琐的计算工作,关键是要捋清楚各个关系,不能搞混了。】。这里直接给出分类的结果:我分别设置了只使用花萼长度这一个特征进行分类以及使用全部四个特征进行分类。(读者可以基于代码很容易地尝试使用其它特征组合)。
A、对训练集0的分类结果
A.1 只使用花萼长度这一个特征进行分类的结果:
图3.3 只使用花萼长度一个特征对训练集0的分类结果
图3.4 只使用花萼长度一个特征对训练集0的分类准确率
A.2 同时使用四个特征进行分类的结果:
图3.5 使用四个特征时对训练集0的分类结果
图3.6 使用四个特征时对训练集0的分类准确率
可以看到准确率有明显提升。
B、对测试集的分类结果
B.1 只使用花萼长度这一个特征进行分类的结果:
图3.7 只使用花萼长度一个特征对测试集的分类结果
图3.8 只使用花萼长度一个特征对测试集的分类准确率
B.2 同时使用四个特征进行分类的结果:
图3.9 使用四个特征时对测试集的分类结果
图3.10 使用四个特征时对测试集的分类准确率
可以看到准确率有明显提升。
3.3 本章小结
本章基于朴素贝叶斯算法对典型的Iris数据集进行了分类实践。分类的结果符合预期,验证了理论和代码的正确性。 不过同时应该注意到:我在求解概率值时(特别是数据集中特征取特定值时的概率),因为这里的特征是连续变量,我使用概率密度值对取特定值下的概率进行估测,而且我假定了该数据集的各个特征是符合高斯分布的变量【这个假设不算是很准确,只是为了方便起见才这样做,读者也可以尝试其它的分布,在实际应用中我们需要基于特征的实际分布情况进行概率的求解,也可以用拟合的方法拟合出对应的分布再求解概率值】。
四、总结
本文探讨朴素贝叶斯算法,具体地,首先对该算法相关的概念进行了介绍,随后给出了基于该算法进行分类实践的典型处理流程,最后结合理论对Iris数据集进行了分类实践,结果符合预期,验证了理论和代码的正确性。有关朴素贝叶斯算法还有很多的拓展:如半朴素贝叶斯、贝叶斯网络等等,感兴趣的读者可以自行查找资料做拓展研究。
本文的工作进一步丰富了专栏[2]:机器学习_墨@#≯的博客-CSDN博客的工具箱!为后续更复杂的深度学习等内容的理解和实践打下了基础。
五、参考资料
[1] KNN算法及基于该算法的回归和分类实践-CSDN博客
[2] 机器学习_墨@#≯的博客-CSDN博客
[3] Machine Learning: 十大机器学习算法 - 知乎
[4] 8.机器学习-十大算法之一朴素贝叶斯(Naive Bayes)算法原理讲解-CSDN博客
[5] UCI Machine Learning Repository
[6] (毫米波雷达数据处理中的)聚类算法(2) – DBSCAN算法及其实践-CSDN博客
[7] 概率密度与功率谱密度的理解与仿真-CSDN博客
六、数据与代码
朴素贝叶斯算法探讨与实践博文对应的代码和数据资源-CSDN文库