通俗简单讲解贝叶斯原理,并python实现贝叶斯分类代码

 

1. 前言

        贝叶斯原理相信大家都非常熟悉了,但是一般情况下,我们的数学水平不怎么地,学生的数学基础也不怎么地,所以要想给学生简单明了的讲明白,还不是一件容易的事情。

       为此,在备课(为河南中医药大学python程序设计)时候,做了充分的准备,争取用通俗易懂的方法尽量的少用公式,给大家讲明白贝叶斯原理的过程,并编程使用贝叶斯算法进行分类。

 

2. 目标

     很简单,还用那个经典的案例,已知样本数据包含4个属性(症状)和1个类别标签(证候),从中学习出经验(先验概率),然后实现贝叶斯公式,进行对新到的样本数据进行分类。假设已知样本数据共12条数据,具体如下:

样本数据

神疲

懒言

乏力

自汗

气虚否

性格好 身高 上进心 嫁与否
1 0 0 0 0
0 1 0 1 0
1 1 0 1 1
0 1 1 1 1
1 0 0 1 0
0 0 0 0 0
1 1 1 0 1
0 1 1 1 1
1 1 1 1 1
0 0 1 1 1
1 1 0 0 0
1 1 0 0 0

   文本中共有12条数据,是有标签(结论)数据,标签是嫁与否;四个属性是帅、性格好、身高、上进心。值为1表示是,为0表示否。

     该数据也可以等价考虑为证候与症状数据,等价转化方式假设如下:四个属性对应四个症状,嫁与否对应气虚否,如上表中第一行和第二行所示。为描述方便,后续文中都用嫁人与否来介绍该案例。

   现在假设来了一个求婚者,该求婚者的属性为(帅=1,性格好=0,高=1,上进心=0),那么根据样本的经验,依据贝叶斯计算出是否嫁给该求婚者?即嫁的概率?不嫁的概率?

3. 解答过程

  3.1 简单说一下贝叶斯,具体如下图所示

 

通俗简单讲解贝叶斯原理,并python实现贝叶斯分类代码_第1张图片

  3.2 用本例子解释贝叶斯,属性为(帅=1,性格好=0,高=1,上进心=0)情况下,贝叶斯的计算,具体如下图所示

通俗简单讲解贝叶斯原理,并python实现贝叶斯分类代码_第2张图片

4. Python程序实现过程

#############################################################
## 案例5. 判断嫁人与否,根据已有的数据集,对于新的求婚者,判断是否同意嫁人?
# 底层原理是朴素贝叶斯,详细资料见我幻灯片和主页链接。
# 老师们把这个例子表演讲一下,演示一下,激发学生的学习兴趣!!!!
## 数据来源:案例数据,使用前将数据文件拷贝到D盘根目录,并改名为“MarrayOrNot”
# 版权所有:河南中医药大学python程序设计不得转载和用于商业用途,仅供河南中医药大学python教学研究使用。
# 特别声明:该案例的相关成果已经申报项目、发表论文!!!大家可以进行掌握学习及变换,这里给出的程序只是最基础的版本实现。如果数据集变成某疾病的症状数据集,原理是一样的!
# 许玉龙,2019年7月16日。
###########################################################
import numpy as np

#下面是加载数据,注意:使用前将数据W文件拷贝到D盘根目录,并改名为“MarrayOrNot”
dataMat=np.loadtxt(open('D:\\MarryOrNot.csv'), delimiter=',', skiprows = 1)#读取含有多个数组的文件
# dataMat为读到的文件的所有数据
row = dataMat.shape[0]#数据行数
col = dataMat.shape[1]#数据列数 
#print(row)
#print(col)
###注意下标从0开始的
#print(dataMat[0,:])#打印第1行数据(即1行所有列)
#print(dataMat[:,1])#打印第2列数据(即2列所有行)

#假设女生现被有一男求婚,属性为:帅、性格不好、高、不上进,求嫁否???

#根据数据集,下面开始计算一些属性(也可称为特征、症状)的先验概率

#print(dataMat)
#print(sum(dataMat[:,4]))

p_marry = sum(dataMat[:,4])/row #P(嫁)的概率
p_marry_not = 1-p_marry  #P(不嫁)的概率

##函数,计算已知x的情况下,y事件发生的概率,即p(y|x)和p(y|~x)
#传入:二维数组,x和y的值是列的索引值
#返回四个值:嫁x情况下y事件发生与不发生的概率p(y|x)、p(~y|x),和不嫁~x情况下y事件发生与不发生的概率p(y|~x)、p(~y|~x)。
def computP(data,x,y):
    row = data.shape[0]#数据行数
    col = data.shape[1]#数据列数 
    marray = 0
    marrayNot=0
    yInMarray = 0
    yInMarrayNot = 0 
    for i in range(row):
        if data[i,x] == 1: #嫁
            marray = marray + 1
            if data[i,y] == 1: #嫁情况下,y事件发生
                yInMarray = yInMarray + 1
        if data[i,x] == 0: #不嫁
            marrayNot = marrayNot + 1
            if data[i,y] == 1:#不嫁情况下,y事件发生
                yInMarrayNot = yInMarrayNot+1
    p_y_marray = yInMarray/marray #嫁情况下y事件发生的概率
    p_n_marray = 1 - p_y_marray   #嫁情况下y事件不发生的概率
    p_y_marrayNot = yInMarrayNot/marrayNot #不嫁情况下y事件发生的概率
    p_n_marrayNot = 1- p_y_marrayNot  #不嫁情况下y事件不发生的概率
    return p_y_marray,p_n_marray,p_y_marrayNot,p_n_marrayNot  
#下面调用函数测试,4表示第5列、0表示第1列。返回四个概率值
pym,pnm,pymnot,pnmnot = computP(dataMat,4,0)#计算在第5列(嫁人与否)情况下,第1列的四个概率值。
#print(ptm)
#print(ptmn)

if __name__ == "__main__":
    print ('*****女生现被有一男求婚,男有属性为:帅、性格不好、高、不上进。')
    print ('     根据已有数据经验,预测该女选择嫁否?')
   # print(p_marry)
    #假设女生现被有一男求婚,男有属性为:帅、性格不好、高、不上进,求该女选择嫁否???
    # 下面分别计算上述属性,在嫁或不嫁时的四个条件概率值
    p_shuai_marry,p_bushuai_marry,p_shuai_marryNot,p_bushuai_marryNot = computP(dataMat,4,0)
    p_x_marry,p_xbad_marry,p_x_marryNot,p_xbad_marryNot = computP(dataMat,4,1)
    p_g_marry,p_gnot_marry,p_g_marryNot,p_gnot_marryNot = computP(dataMat,4,2)
    p_s_marry,p_snot_marry,p_s_marryNot,p_snot_marryNot = computP(dataMat,4,3)
    
    #嫁的情况下,上述属性发生的概率为p(嫁)*p(帅|嫁)*p(性格不好|嫁)*p(高|嫁)*p(不上进|嫁)
    p_e_marry = p_marry*p_shuai_marry*p_xbad_marry* p_g_marry*p_snot_marry
   #不嫁的情况下,上述属性发生的概率为p(不嫁)*p(帅|不嫁)*p(性格不好|不嫁)*p(高|不嫁)*p(不上进|不嫁)
    p_n_marry = p_marry_not*p_shuai_marryNot*p_xbad_marryNot* p_g_marryNot*p_snot_marryNot
    
    #根据贝叶斯公式计算预测嫁或不嫁的概率
    p_yuce_marry = p_e_marry/(p_e_marry+p_n_marry)
    p_yuce_marryNot = p_n_marry/(p_e_marry+p_n_marry)
    print("*****预测结果如下")
    print ("预测嫁的概率是: %3.2f" %p_yuce_marry)
    print ("预测不嫁的概率是: %3.2f" %p_yuce_marryNot)
    print ("又高又帅,不管其他就嫁了,看来已有的数据经验是外表主义范、外貌协会啊!")
    print ("??思考:能否对其他属性时,也进行预测呢?")
    print ("??如何修改程序使可输入属性,得到预测?这些是本课程学完后要达到的水平")
    print ("更多相关原理,请关注我的学者主页课程资料")

运行结果:

*****女生现被有一男求婚,男有属性为:帅、性格不好、高、不上进。

     根据已有数据集经验,使用贝叶斯预测该女选择嫁否?

*****预测结果如下

预测嫁的概率是: 1.00

预测不嫁的概率是: 0.00

又高又帅,不管其他就嫁了,看来已有的数据经验是外表主义、外貌协会啊!

??思考:能否对其他属性时,也进行预测呢?

??如何修改程序使可输入属性,得到预测?如果数据是某疾病症状数据呢??这些是本课程学完后要达到的水平更多相关原理,请关注我的学者主页课程资料

5. 总结、参考及感谢

       5.1 贝叶斯的简单描述就是:由先验概率求出后验概率,先验概率可以从样本数据中容易求出,而后验概率即是我们要预测的分类结果,不容易求出。贝叶斯公式等号右边分子可以展开转换为条件概率容易计算得出、分母可以通过全概率公式展开容易计算得出,分子是分母的一部分。这样就非常好理解了。

      5.2 这里是用的朴素贝叶斯来计算,它要满足条件之间相互独立,即帅与上进没有关系、性格好与高之间也没有关系,任何属性之间都是没有关系滴。

     5.3 虽然贝叶斯公式的思想很简单,但是它在分类和机器学习应用时候,效果性能还是不错的,能够学习出样本数据的经验

    5.4 感谢bd-liuming博主,参考了博客的https://blog.csdn.net/fisherming/article/details/79509025数据来源。 

你可能感兴趣的:(Python学习)