贝叶斯的学习需要概率论的基本知识,条件概率、全概率、加乘法定理、贝叶斯公式等等基础知识可参考博客“数学素养”的“概率论”相关章节。
一、朴素贝叶斯假设和公式
朴素贝叶斯是贝叶斯决策理论的一部分,我们称之为“朴素”(native),是因为整个形式化过程只做最原始、最简单的假设。朴素贝叶斯分类器中的假设是:
- 每个特征都是独立的
- 每个特征同等重要
贝叶斯决策理论的核心思想是,分类时,我们会选择高概率对应的类别,即选择具有最高概率的决策。
可得到如下形式:
怎么理解?
- P(A)称为”先验概率”(Prior probability),即在B事件发生之前,我们对A事件概率的一个判断。
- P(A|B)称为”后验概率”(Posterior probability),即在B事件发生之后,我们对A事件概率的重新评估。
- P(B|A)/P(B)称为”可能性函数”(Likelyhood),这是一个调整因子,使得预估概率更接近真实概率。
所以,条件概率可以理解成下面的式子:
后验概率 = 先验概率 x 调整因子
这就是贝叶斯推断的含义。我们先预估一个”先验概率”,然后加入实验结果,看这个实验到底是增强还是削弱了”先验概率”,由此得到更接近事实的”后验概率”。
在这里,如果”可能性函数”P(B|A)/P(B)>1,意味着”先验概率”被增强,事件A的发生的可能性变大;如果”可能性函数”=1,意味着B事件无助于判断事件A的可能性;如果”可能性函数”<1,意味着”先验概率”被削弱,事件A的可能性变小。
二、朴素贝叶斯公式计算实例
为方便理解上述公式,对于规律总结来讲,可写成:
P(规律|现象)=P(现象|规律)P(规律)/P(现象)
对于分类任务来讲,可写成:
P(类别|特征)=P(特征|类别)P(类别)/P(特征)
实例1
有两个碗,1号碗里有30颗水果糖和10块巧克力糖,2号碗里有20颗水果糖和20块巧克力糖。然后把碗盖住。随机选择一个碗,从里面摸出了一颗水果糖。问题:这颗水果糖来自1号碗的概率是多少?
我们希望得到概率P(1号碗|水果糖),但怎样进行计算并非显而易见。问题如果换成在1号碗中水果糖的概率P(水果糖|1号碗)则简单的多,但可惜的是条件概率并不满足交换律,P(1号碗|水果糖)和P(水果糖|1号碗)并不相同。那么可以使用贝叶斯定理。
P(1号碗|水果糖)=(P(水果糖|1号碗)/P(水果糖))*P(1号碗)
- 其中两个碗的选择是随机的,P(1号碗)=1/2。
- P(水果糖|1号碗)=30颗水果糖/(30颗水果糖和10块巧克力糖)=3/4。
- P(水果糖),可以使用全概率公式计算,其实是1/2 × 30/40 + 1/2 × 20/40=5/8。
- 可能性函数为(3/4)/(5/8)=6/5
最终得出P(1号碗|水果糖)=1/2 × 6/5 =3/5。
可以看出先验概率为1/2,当有了抓出的是水果糖这个条件后,可能性函数为6/5,使得后验概率提升到了3/5。
实例2
男士的条件会影响到女士是否愿意嫁,数据如下:
样貌 | 性格 | 身高 | 上进心 | 嫁不嫁 |
---|---|---|---|---|
帅 | 不好 | 矮 | 不上进 | 不嫁 |
不帅 | 好 | 矮 | 上进 | 不嫁 |
帅 | 好 | 矮 | 上进 | 嫁 |
不帅 | 好 | 高 | 上进 | 嫁 |
帅 | 不好 | 矮 | 上进 | 不嫁 |
不帅 | 不好 | 矮 | 不上进 | 不嫁 |
帅 | 好 | 高 | 不上进 | 嫁 |
不帅 | 好 | 高 | 上进 | 嫁 |
帅 | 好 | 高 | 上进 | 嫁 |
不帅 | 不好 | 高 | 上进 | 嫁 |
帅 | 好 | 矮 | 不上进 | 不嫁 |
帅 | 好 | 矮 | 不上进 | 不嫁 |
那么有一个男生,四个特点分别是不帅,性格不好,身高矮,不上进,请你判断(分类)一下女生是嫁还是不嫁?
问题可以变为P(嫁|不帅,性格不好,矮,不上进) 和P(不嫁|不帅,性格不好,矮,不上进) 这两个概率哪个高?
根据贝叶斯公式,有以下2个:
1、P(嫁|不帅,性格不好,矮,不上进) = P(嫁) × P(不帅,性格不好,矮,不上进|嫁)/P(不帅,性格不好,矮,不上进)
2、P(不嫁|不帅,性格不好,矮,不上进) = P(不嫁) × P(不帅,性格不好,矮,不上进|不嫁)/P(不帅,性格不好,矮,不上进)
- P(嫁)=P(不嫁)=6/12
- P(不帅,性格不好,矮,不上进|嫁)这个是联合概率,=P(不帅|嫁) × P(性格不好|嫁) × P(矮|嫁) × P(不上进|嫁)=1/2 × 1/6 × 1/6 × 1/6 =1/432
- P(不帅,性格不好,矮,不上进|不嫁)=P(不帅|不嫁) × P(性格不好|不嫁) × P(矮|不嫁) × P(不上进|不嫁)=1/3 × 1/2 × 1 × 2/3 =1/9
- P(不帅,性格不好,矮,不上进)套用全概率公式,=P(嫁) × P(不帅,性格不好,矮,不上进|嫁)+ P(嫁) × P(不帅,性格不好,矮,不上进|不嫁)=1/2 × 1/392 + 1/2 × 1/9=49/392
可得出P(嫁|不帅,性格不好,矮,不上进) =(1/432)/(49/432)=1/49,P(不嫁|不帅,性格不好,矮,不上进)==(1/9)/(49/432)=48/49。可以看出不嫁的概率远远大于嫁的概率。
三、关键词过滤分类器的代码实现
以社区留言评论为例,我们要屏蔽侮辱性的言论,所以要构建一个快速过滤器,如果某条留言使用了负面或者侮辱性的语言,那么就将该留言标志为内容不当。过滤这类内容是一个很常见的需求。
准备数据和标签
对此问题建立两个类型:侮辱类和非侮辱类,使用1和0分别表示。
1 | ''' |
数据处理
我们把文本看成单词向量或者词条向量,也就是说将句子转换为向量。考虑出现所有文档中的单词,再决定将哪些单词纳入词汇表或者说所要的词汇集合,然后必须要将每一篇文档转换为词汇表上的向量。简单起见,我们先假设已经将本文切分完毕,存放到列表中,并对词汇向量进行分类标注。
1 | def createVocabList(dataSet): |
测试调用
1 | import bayes |
训练朴素贝叶斯分类器
1 | def trainNB0(trainMatrix, trainCategory): |
使用分类器实施分类
1 | def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1): |
测试
1 | testEntry = ['love', 'my', 'dalmation'] # 测试样本1 |
输出结果:
1 | ['love', 'my', 'dalmation'] 属于非侮辱类 |