美文网首页Python建模与NLP程序员工具癖
使用贝叶斯定理判断骰子是否偏心

使用贝叶斯定理判断骰子是否偏心

作者: dalalaa | 来源:发表于2017-10-28 12:26 被阅读121次

    假设有一枚骰子,投掷了100次,其中出现了26次1点,25次2点,18次3点,10次4点,14次5点,8次6点。
    下面是最常见的一种骰子各面展开图:


    image.png

    可以看到1/2/3点出现较多,且这三个点数在骰子中是相连的,初步判断可能骰子的重心偏向了1/2/3点的公共角方向。但是仅凭猜测不能解决问题,还需要数据的支持。仅凭这100次结果如何判断筛子是否偏心呢?以下为具体步骤:
    需要对六个面分别分析

    1点

    设定先验概率分布

    设出现一点的概率分布为均匀分布(即假设进行100组掷骰子实验,每组实验中掷骰子99次,其中,出现0次、1次、2次、3次……99次一点的实验组均为一组),共有100个假设(H0到H99)假设Hx,掷1点的概率为x,每个假设成立的初始概率相同,均为1%。

    import matplotlib.pyplot as plt
    import numpy as np
    pro = [1 for i in range(1,101)]#Hx的先验概率分布
    pro = np.array(pro)
    plt.plot(pro/100.00,'b')
    x = [i for i in range(1,101)]#Hx对应的掷一点概率
    x = np.array(x)
    

    使用数据修正先验分布

    本次实验中实际出现了26次1点,74次非1点,设点数为B,则B=1出现了26次,B=0出现了74次。我们将使用这些数据来修正先验分布。

    def likelihood(data,x):#似然度
        if data == 'T':
            return x/100.00
        else:
            return 1-x/100.00
            
    datas = 'T'*26+'F'*74
    for data in datas:
        pro = pro * likelihood(data,x)#后验分布
    pro = pro/sum(pro)#归一化
    
    plt.plot(pro,'g')
    
    
    图中蓝色为先验分布、绿色为后验分布

    求置信区间

    为了求该分布的90%置信区间,我们需要将pro累加,记录下对应于累积概率5%和95%的值,即为置信区间。

    dic = dict(zip(x,pro))
    def Percentile(dic,percentage):
        p = percentage/100.00
        total = 0
        for x,pro in dic.items():
            total += pro
            if total >= p:
                return x
    
    print([Percentile(dic,5),Percentile(dic,95)])
    

    结果:

    [20, 34]
    

    置信区间并不包括均匀骰子掷一点的概率16.67%,所以可以认为,1点出现的频率过高,重心可能偏向一点的对面,即6点。

    其余点数

    import matplotlib.pyplot as plt
    import numpy as np
    
    datas_list = [
                  'T'*26+'F'*74,
                  'T'*25+'F'*75,
                  'T'*18+'F'*82,
                  'T'*10+'F'*90,
                  'T'*14+'F'*86,
                  'T'*8+'F'*92
                  ]
    pro = [1 for i in range(1,101)]#Hx的先验概率分布
    pro = np.array(pro)
    plt.plot(pro/100.00)
    x = [i for i in range(1,101)]#Hx对应的掷一点概率
    x = np.array(x)
    
    def likelihood(data,x):#似然度
        if data == 'T':
            return x/100.00
        else:
            return 1-x/100.00
            
    
    def update(datas,x,pro,i):
        for data in datas:
            pro = pro * likelihood(data,x)#后验分布
        pro = pro/sum(pro)#归一化
    
        plt.plot(pro)
    
        dic = dict(zip(x,pro))
        return dic
    def Percentile(dic,percentage):
        p = percentage/100.00
        total = 0
        for x,pro in dic.items():
            total += pro
            if total >= p:
                return x
    i = 1
    for datas in datas_list:
        dic= update(datas,x,pro,i)
        print('%r点的置信区间为:' % i ,[Percentile(dic,5),Percentile(dic,95)])
        i+=1
        if Percentile(dic,95) < 16.67:
            print('重心偏向')
        elif Percentile(dic,5) > 16.67:
            print('重心远离')
        else:
            print('无偏')
            
    plt.legend(labels = ['h',1,2,3,4,5,6])
    plt.show()
    

    1点的置信区间为: [20, 34]
    重心远离
    2点的置信区间为: [19, 33]
    重心远离
    3点的置信区间为: [13, 25]
    无偏
    4点的置信区间为: [6, 16]
    重心偏向
    5点的置信区间为: [9, 21]
    无偏
    6点的置信区间为: [5, 14]
    重心偏向

    各个点数的概率分布图如下:


    各点概率分布

    结论

    骰子重心有偏,偏向4点和6点。


    image.png

    本实例由《贝叶斯思维:统计建模的Python学习法》中关于欧元硬币的实例引申而来。

    相关文章

      网友评论

        本文标题:使用贝叶斯定理判断骰子是否偏心

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