假设有一枚骰子,投掷了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学习法》中关于欧元硬币的实例引申而来。
网友评论