美文网首页
朴素贝叶斯分类器笔记-Python实现

朴素贝叶斯分类器笔记-Python实现

作者: 不想放开的骆驼 | 来源:发表于2020-05-20 09:18 被阅读0次

    前言:

    上篇笔记介绍了贝叶斯原理,写这篇笔记,算是承上启下,更深入的学习下贝叶斯原理并应用它。同样,我用Python实现了一个简单的预估「嫁不嫁」的问题的分类器,帮助理解朴素贝叶斯。

    朴素贝叶斯介绍:

    朴素贝叶斯基于贝叶斯公式,“朴素”是因为「假设各特征之间相互独立」,这一假设使朴素贝叶斯算法变得简单,也牺牲了一定的分类准确性。

    优点:

    算法简单、分类过程时空开销少

    缺点:

    「朴素」的假设牺牲了一定的分类准确性

    贝叶斯公式:

    image

    换成分类任务的表达式:

    image

    则朴素贝叶斯公式:

    image

    (图片来自网络)

    案例:

    首先,数据如下:

    image

    (图片来自网络)

    现在给我们的问题是,如果一对男女朋友,男生想女生求婚,男生的四个特点分别是不帅,性格不好,身高矮,不上进,请你判断一下女生是嫁还是不嫁?

    根据朴素贝叶斯公式,我们转化为这样的公式:

    image

    展开后的公式,可以看到,分子和分母有一定的重叠内容,所以我们只需要算

    P(嫁)×P(不帅、性格不好、矮、不上进|嫁)

    P(不嫁)P(不帅|不嫁)P(性格不好|不嫁)P(矮|不嫁)P(不上进|不嫁)

    即可

    P(嫁)=P(不嫁)= 1/2 (我这里有点疑惑,P(嫁)是先验概率,我是取所有样本种「嫁」所占比例为先验概率,不知正确与否)

    P(性格不好|嫁)=1/6、
    P(矮|嫁)=1/6、
    P(不上进|嫁)=1/6、
    P(不嫁)=1/2、P(不帅|不嫁)=1/3、
    P(性格不好|不嫁)=1/2、
    P(矮|不嫁)=1、
    P(不上进|不嫁)=2/3

    代入上边展开了的公式:

    P(嫁)P(不帅|嫁)P(性格不好|嫁)P(矮|嫁)P(不上进|嫁)=1/2 * 1/2 * 1/6 * 1/6 * 1/6=1/864

    P(不嫁)P(不帅|不嫁)P(性格不好|不嫁)P(矮|不嫁)P(不上进|不嫁)=1/2 * 1/3 * 1/2 * 1* 2/3=1/18

    得出:

    P(嫁|不帅、性格不好、矮、不上进)=(1/864) / (1/864+1/18)=1/49=2.04%

    P(不嫁|不帅、性格不好、矮、不上进) = 1 - P(嫁|不帅、性格不好、矮、不上进)=
    97.96%

    Python代码:

    class naive_bayes(object):
        """naive_bayes demo"""
        def __init__(self, data):
            super(naive_bayes, self).__init__()
            self.data = data
            self.sample_size = len(self.data)
            self.marry = 0 # 样本中,嫁的计数
            self.yes_or_not = 1 # 是否嫁,默认为嫁
            self.counter_marry = [0,0,0,0] # 对符合参数的嫁情况计数
            self.counter_not_marry = [0,0,0,0] # 对符合参数的不嫁情况计数
    ​
        def prior(self):
            for x in xrange(1,10):
                pass
        def likelihood(self):
            for x in range(self.sample_size):
                if self.data[x][-1] == 1:
                    self.marry+=1 # 嫁的总数
                    for i in range(len(self.user)):
                        if self.data[x][i] == self.user[i]:
                            self.counter_marry[i]+=1
                else:
                    for i in range(len(self.user)):
                        if self.data[x][i] == self.user[i]:
                            self.counter_not_marry[i]+=1
        def calc(self):
            # 计算概率
            # left 是 P(A) * P(B|A),right 是 P(B|A') * P(A')
            left = 1 ; right = 1 
            self.not_marry = self.sample_size - self.marry
            for x in range(len(self.counter_marry)):
                left *= self.counter_marry[x] / self.marry
                right *= self.counter_not_marry[x] / self.not_marry
            left *= self.marry / self.sample_size
            right *= self.not_marry / self.sample_size
            return left / (left+right)
        def print(self,*args):
            self.user = args
            self.likelihood()
            PR = self.calc()
            if PR < 0.5:
                self.yes_or_not = 0
            print("这个男人「不帅,性格不好,矮,不上进」嫁吗\n")
            if self.yes_or_not == 1:
                print("嫁!")
                print("P(嫁|不帅、性格不好、矮、不上进)={:.2%}".format(PR))
                print("P(不嫁|不帅、性格不好、矮、不上进)={:.2%}".format(1-PR))
            else:
                print("不嫁!")
                print("P(嫁|不帅、性格不好、矮、不上进)={:.2%}".format(PR))
                print("P(不嫁|不帅、性格不好、矮、不上进)={:.2%}".format(1-PR))
    def main():
        帅 = 1; 不帅 = 0;性格好 = 1;性格不好 = 0;高 = 1;矮 = 0;上进 = 1;不上进 =0;嫁 = 1; 不嫁 = 0;
        data = [[帅,性格不好,矮,不上进,不嫁],
        [不帅,性格好,矮,上进,不嫁],
        [帅,性格好,矮,上进,嫁],
        [不帅,性格好,高,上进,嫁],
        [帅,性格不好,矮,上进,不嫁],
        [不帅,性格不好,矮,不上进,不嫁],
        [帅,性格好,高,不上进,嫁],
        [不帅,性格好,高,上进,嫁],
        [帅,性格好,高,上进,嫁],
        [不帅,性格不好,高,上进,嫁],
        [帅,性格好,矮,不上进,不嫁],
        [帅,性格好,矮,不上进,不嫁]]
        a = naive_bayes(data)
        a.print(不帅,性格不好,矮,不上进)
    if __name__ == '__main__':
        main()
    

    运行结果:

    image

    结言:

    因为数据比较少,只用了内置的列表存放数据,没有用numpy这样的库。更骚的是,我用了中文变量(没错,Python支持中文变量)。写这篇笔记,也是在实践费曼技巧,以教促学。如果笔记有错误,麻烦回复提醒下,我会改正!

    参考文献:

    1. https://blog.csdn.net/fisherming/article/details/79509025

    相关文章

      网友评论

          本文标题:朴素贝叶斯分类器笔记-Python实现

          本文链接:https://www.haomeiwen.com/subject/zrfgohtx.html