用Python实现贝叶斯定理(附代码)
写作说明
上一期我们讲了贝叶斯分类器,其中有很多的概率基础知识和贝叶斯定理。但是讲解的很没有重点,前半部分讲的是贝叶斯基础知识,最后很突兀的插进来一个文本分析-贝叶斯分类器。很多童鞋看到很累。其实上一期和本期都想附上《贝叶斯思维:统计建模的Python学习法》书中的代码,但我看了下源码,发现代码太长了信息量太大,不是我一篇文章就能展示的明白的。
今天我就早起翻看这本书,根据书上的讲解和自己的理解,用Python实现的一个简单的贝叶斯的脚本。本文只是用来验证自己贝叶斯定理是否理解,是否能自己动手实现,本身这脚本并没有什么高大上的功能,如果有的话,唯一的功能就是能用来做贝叶斯数学题O(∩_∩)O哈哈~。
曲奇饼案例
假设有两碗曲奇饼,碗A包含30个香草曲奇饼和10个巧克力曲奇饼,碗B这两种曲奇饼各20个。 现在假设你在不看的情况下随机地挑一个碗拿一块饼,得到了一块香草曲奇饼。
问题:从碗A渠道香草曲奇饼的概率是多少
思路
这是一个条件概率问题,我们希望得到P(碗A|香草饼),
现在我们很容易知道P(香草饼|碗A)=3/4,
如果将两者联系起来,那么P(碗A|香草饼)就很容易算得。
但可惜P(碗A|香草饼)与P(香草饼|碗A)是不同的。
不过贝叶斯定理却可以通过一个概率得到另一个概率。
贝叶斯定理
联合概率可交换,即 P(A and B)=P(B and A)
对于任意事件A、B都独立,因此联合概率P(A and B)=P(B)P(A|B)
两步骤执行交换,即P(B and A)=P(A)P(B|A)
因为步骤1等式,有如下等式成立P(B)P(A|B)=P(A)P(B|A)
最后等式两端除以P(B),得到P(A|B)=P(A)P(B|A)/P(B)
这就是贝叶斯定理,推导过程比中学时要简单很多。先来计算下曲奇饼问题
本题数学的计算过程
P(碗A|香草饼)= P(碗A)*P(香草饼|碗A)/P(香草饼)
P(碗A)=1/2
P(香草饼|碗A)=3/4
P(香草饼)=50/(50+30)=5/8
所以最后经过计算
P(碗A|香草饼)=3/5=0.6
先验概率、后验概率、似然度、标准化常量
我觉得在python实现代码前最好大家能够记住先验概率、后验概率这些概念(如果能理解更好)。 对上述贝叶斯定理的理解,还有一种解释思路,叫做“历时诠释”。“历时”意味着某些事情随着时间而发生,即假设的概率随着看到新数据而发生变化。
在考虑H(Hypothsis)和D(Data)情况下,贝叶斯定理的表达式可以写成:
P(H|D)=P(H)P(D|H)/P(D)
在考虑H和D的情况下,每项意义如下:
P(H)称为先验概率,即在得到新数据前某一假设的概率。如没有得到掷硬币结果前,我们先假设正反面概率各位50%。
P(H|D)称为后验概率,即看到新数据后,我们要计算的该假设的概率。
P(D|H)是该假设下得到这一数据的概率,称为似然度。
P(D)是任何假设下得到这一数据的概率,称为标准化常量。
本题目Python的实现分析
了解了前面的铺垫,现在好办了。希望大家没有看晕,都能坚持到现在。
首先定义Bayes类,初始化创建一个dict类型的容器container。该容器是为了储存贝叶斯各项信息。key键存储假设,value值存储概率
Set方法是给容器添加先验假设及先验概率
Mult方法:根据key查找到先验概率,并更新概率。
Normalize方法:归一化(建议大家等会运行代码时候看下有无Normalize的区别,就能理解归一化这一含义)
Prob方法:返回某一事件的概率
好了,有了前面的铺垫,可以附上我的代码
class Bayes(object):
def __init__(self):
self._container = dict()
def Set(self,hypothis,prob):
self._container[hypothis]=prob
def Mult(self,hypothis,prob):
old_prob = self._container[hypothis]
self._container[hypothis] = old_prob*prob
def Normalize(self):
count = 0
for hypothis in self._container.values():
count=count+hypothis
for hypothis,prob in self._container.items():
self._container[hypothis]=self._container[hypothis]/count
def Prob(self,hypothis):
Prob = self._container[hypothis]
return Prob
用python解下曲奇饼题
#实例化Bayes类
bayes = Bayes()
#先验概率
bayes.Set('Bow_A',0.5) #P(碗A)=1/2
bayes.Set('Bow_B',0.5) #P(碗B)=1/2
#后验概率
bayes.Mult('Bow_A',0.75) #P(香草饼|碗A)=3/4
bayes.Mult('Bow_B',0.5) #P(香草饼|碗B)=1/2
bayes.Normalize()
prob = bayes.Prob('Bow_A')#P(碗A|香草饼)
print('从碗A渠道香草曲奇饼的概率:{}'.format(prob))
运行结果
从碗A渠道香草曲奇饼的概率:0.6
更多内容
文本分析
数据分析
神奇的python
爬虫
【视频】有了selenium,小白也可以自豪的说:“去TMD的抓包、cookie”
【视频】快来get新技能--抓包+cookie,爬微博不再是梦