第三天机器学习啦!今天我们主要来一个比较“朴素”的算法,朴素贝叶斯(Naive Bayes),至于它为什么朴素我们待会儿再讲吧!
首先,我们来看一下贝叶斯算法,它是干嘛的呢?
贝叶斯算法是一类分类算法的统称,这类算法全是基于贝叶斯定理,所以叫贝叶斯算法,那朴素贝叶斯呢?他是贝叶斯分类算法中最简单的一个算法,它的朴素之处在于事件独立。
我们现在先来讲讲贝叶斯理论吧:
现在我们有个数据集,它由两类组成,一类是圆形点,一类是三角形点,如下图:
我们现在用P1(x,y)表示圆点的概率,用P2(x,y)表示三角形点的概率,现在我们可以通过P1,P2的概率来判断他们的类别:
if P1(x,y)>P2(x,y), then 类别为圆点
if P1(x,y)<P2(x,y), then 类别为三角形点
即选择高概率对应的类别,这也就是贝叶斯的核心决策思想:选择具有最高概率的决策。
现在我们来看看条件概率,什么是条件概率?
【条件概率:两个事件独立,在一个事件已经发生的情况下去求另一件事发生的概率。所谓 独立(independence) 指的是统计意义上的独立,即一个特征出现的可能性与它和其他特征相邻没有关系,而这个独立也就是朴素贝叶斯朴素的含义了。】
举个例子来解释一下,我有7个乒乓球,放在一个黑色不透明的箱子里。3个白的,4个黄的,取到白球的概率是多少?
这个题目应该很简单,直接就可以算出答案,为3/7。
那我们现在把题目修改一下:
现在有两个黑色不透明密闭的盒子,第一个盒子放2个白色2个黄色乒乓球,第二个盒子放1个白的,2个黄色的。现在我们要求:从第二个盒子里取出白球的概率。这个就是我们所谓的条件概率了。
P(白|在二盒子)就是我们所要求的结果
P(白|在二盒子)= P(白色且在二盒子)/P(在二盒子)
我们之前说了贝叶斯定理,那么我们现在就需要来介绍一下,贝叶斯所表达的核心定理是什么呢?
下面我们通过一张图,一个公式来介绍:
首先我们介绍一下我们画的图:矩形框是我们的一个样本空间,代表所有可能发的结果,图中黄颜色的A就是事件A发生的可能性,想要表示成概率[P],那么A发的概率的话就是P(A),那途中B事件发生的概率也就是P(B)了,那么A和B中间重复的一部分是什么意思呢,就是A和B同时一起发生的概率,我们可以用P(AB)来表示。为了去了解贝叶斯,我们还需要去了解一个东西P(B|A)是什么意思?
P(B|A)所代表的意思是,在A事件已经发生的前提下发生B事件的概率(这个就是条件概率了)
了解了这些之后,我们下面来看公式:
这个公式的意思是,求在A已经发生的情况下B事件发生的概率,通过B事件发生的概率乘以B事件发生的前提下A事件发生的概率再除以A事件发生的概率。
这就是贝叶斯公式。
这是最基本的贝叶斯的概念,那我们然后将这个公式与机器学习挂上钩呢?
很简单,令A=特征,B=类别,这样不就是我们所想要的公式吗?
P(类别|特征)=P(特征|类别)*P(类别)/P(特征)
最后只要求P(类别|特征)即可。
Now,我们现在使用条件概率进行分类
之前我们是只有两类,圆点类和三角形点类,但是在实际应用中却不止这么两个类或者说我们只需要从一些类别中调出对我们有效的类别,这个时候我们就需要条件概率了,引入类别class,对于之前的圆点和三角形点我们简写成c1,c2,那么P(c1|x,y)=P(x,y|c1)*P(c1)/P(x,y)。以此推一下,我们求点想,y来自某个类别ci的概率:
在做垃圾邮件分类的时候,一份邮件就是实例,而电子邮件中的一些能辨别它是否为垃圾邮件的词就是我们所要找的特征,对于,每个词出现的频率为该特征的值,这样得到的特征数目就会和我们对比的目标词汇一样多。
朴素贝叶斯是上面介绍的贝叶斯分类器的一个扩展,是用于文档分类的常用算法。下面我们来做一做朴素贝叶斯分类的实践项目。
首先我们明确一下我们要用朴素贝叶斯干嘛,它的工作原理是?
这边我们写成Python的语法结构:
了解完它的工作原理之后,下面我们准备开发一个简单的Python分类的项目,我们先来整理一下我们的开发步骤:
Step1:收集数据
Step2:准备数据,准备成我们想要的数字类型
Step3:分析数据,对于具有大量的特征时我们使用直方图
Step4:训练算法,计算不同独立特征的条件概率
Step5:测试算法,看算法的效率如何,如果效率很低,返回Step4
Step6:使用已经训练好的算法。
Step1: 收集数据,这里我们是创建自己的数据集
Step2:准备数据,从文本中构建词向量
便利查看单词的位置
Step3:分析数据,检查词条确保解析的正确性
在我们现在的这个代码中就很简单了,检查函数的有效性,我们多运行几次函数,输入数据,查看该词汇出现的次数
输出结果:
[0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0]
多测几次.....
Step4:训练算法,对于词向量的计算概率
取代之前的特征值想x,y,我们用一个向量w来表示,w里面可以包含多个值,我们的计算公式就变成了:
利用这个公式计算不同的ci对呀的值,如何比较他们概率的大小。
那么问题来了,我们没有P(w)怎么办,我们之前都没有计算P(w),现在没有这个值我们该怎么去比较大小呢?
OK,那么我们来想一下,ci一定的时候,我们对应的P(w)是不是也是一定的?结果当然是肯定的,对于我们刚刚创建的数据集,无论是0还是1他们各自对应的P(w)都特么事个定值,简而言之我们就可以直接去比较分子的大小了,直接通过分子的大小来确定分类。
这边我们有个公式介绍一下,就是将w向量展开成所有的独立特征的时候,我们可以朴素贝叶斯假设,即:
p(w | ci) = (w0 | ci)p(w1 | ci)p(w2 | ci)...p(wn | ci)
这样我们就可以来写训练函数了:
这边我们要定义两个参数,第一个trainMatrix,它代表文件单词矩阵,即我们的w,第二个参数是trainCategory,代表文件对应的类别。
Step5:测试算法(优化)
在测试算法的时候,我们发现当计算p(w0|ci) * p(w1|ci) * p(w2|ci)... p(wn|ci)的时候,由于这个概率本身就都非常小,这些很小的数相乘会造成下溢出,答案往往接近0,无法准确的将结果表达出来(大家都是贼接近0的数,怎么比),这个时候你的高中数学就可以帮到你的忙了。我们在高中学过,与一次函数成正比的函数(就是图像趋势相同),没错!就是对数函数,而且这边的对数函数我们可以将原来的乘法计算换算成加法计算,减少了我们的计算量,同时,更重要的是解决了下溢出的问题。
我们需要:from math import log
Step6:使用算法
搞定,分分钟实现了朴素贝叶斯!
代码地址: