两个骰子的朴素贝叶斯方法
Naive Bayes method for two dice
我需要帮助实现两个骰子的朴素贝叶斯方法 - 其中一个是 'normal' 有六个面的骰子,这样每个面都有相等的概率 1/6
.另一个是加载的骰子,每两次尝试都会给出结果 6
。
我的程序应该将骰子的选择作为输入,然后模拟十次掷骰子的序列。
我必须从赔率开始 1:1
,然后应用朴素贝叶斯方法在每个结果后更新赔率,以决定选择哪个骰子(最有可能)。它应该 return True
如果最有可能的骰子是已加载的骰子,否则 False
。
我的代码:
import numpy as np
p1 = [1/6, 1/6, 1/6, 1/6, 1/6, 1/6] # normal
p2 = [1/10, 1/10, 1/10, 1/10, 1/10, 1/2] # loaded
def roll(loaded):
if loaded:
print("a loaded die")
p = p2
else:
print("a normal die")
p = p1
# roll the dice 10 times
sequence = np.random.choice(6, size=10, p=p) + 1
for roll in sequence:
print("rolled %d" % roll)
return sequence
def bayes(sequence):
odds = 1.0 # start with odds 1:1
for roll in sequence:
for i in range(len(p1)):
r = p1[i]/p2[i]
if r == 10/6:
odds = 1.0*(10/6)**roll
elif r == 1/3:
odds = 1.0*(1/3)**roll
if odds > 1:
return True
else:
return False
sequence = roll(True)
if bayes(sequence):
print("More likely loaded")
else:
print("More likely normal")
我们的想法是区分加载骰子的概率为 0.1 和 0.5 的情况,但遗憾的是代码无法正常工作。你能帮帮我吗?
if r == 10/6:
odds = 1.0*(10/6)**roll
elif r == 1/3:
odds = 1.0*(1/3)**roll
您是否考虑过这两种情况都不是这种情况的可能性?让我们直接检查一下:
>>> ((1/6) / (1/10)) == 10/6
False
嗯。原来你can't expect floating-point numbers to do that.
但是无论如何都没有理由执行此条件检查,因为无论 r 的值如何,您都想做基本相同的事情。
简单:
odds = 1.0 * r**roll
另外,您不需要 Numpy(查看 random.choices
). There's also a Fraction
type provided in the standard library。
给定 10 次掷骰子,如果掷骰子是公平的,则您获得准确掷骰顺序的概率是 (1/6)**10
给定 10 卷已加载的骰子,您获得准确的掷骰顺序的概率是 (1/10)**(number of non-sixes) * (1/2) ** (number of sixes)
注意这两个值只是
math.product(p1[i - 1] for i in sequence)
math.product(p2[i - 1] for i in sequence)
鉴于两个骰子的先验概率是1:1,你可以比较这两个概率并选择最大的。
我需要帮助实现两个骰子的朴素贝叶斯方法 - 其中一个是 'normal' 有六个面的骰子,这样每个面都有相等的概率 1/6
.另一个是加载的骰子,每两次尝试都会给出结果 6
。
我的程序应该将骰子的选择作为输入,然后模拟十次掷骰子的序列。
我必须从赔率开始 1:1
,然后应用朴素贝叶斯方法在每个结果后更新赔率,以决定选择哪个骰子(最有可能)。它应该 return True
如果最有可能的骰子是已加载的骰子,否则 False
。
我的代码:
import numpy as np
p1 = [1/6, 1/6, 1/6, 1/6, 1/6, 1/6] # normal
p2 = [1/10, 1/10, 1/10, 1/10, 1/10, 1/2] # loaded
def roll(loaded):
if loaded:
print("a loaded die")
p = p2
else:
print("a normal die")
p = p1
# roll the dice 10 times
sequence = np.random.choice(6, size=10, p=p) + 1
for roll in sequence:
print("rolled %d" % roll)
return sequence
def bayes(sequence):
odds = 1.0 # start with odds 1:1
for roll in sequence:
for i in range(len(p1)):
r = p1[i]/p2[i]
if r == 10/6:
odds = 1.0*(10/6)**roll
elif r == 1/3:
odds = 1.0*(1/3)**roll
if odds > 1:
return True
else:
return False
sequence = roll(True)
if bayes(sequence):
print("More likely loaded")
else:
print("More likely normal")
我们的想法是区分加载骰子的概率为 0.1 和 0.5 的情况,但遗憾的是代码无法正常工作。你能帮帮我吗?
if r == 10/6:
odds = 1.0*(10/6)**roll
elif r == 1/3:
odds = 1.0*(1/3)**roll
您是否考虑过这两种情况都不是这种情况的可能性?让我们直接检查一下:
>>> ((1/6) / (1/10)) == 10/6
False
嗯。原来你can't expect floating-point numbers to do that.
但是无论如何都没有理由执行此条件检查,因为无论 r 的值如何,您都想做基本相同的事情。
简单:
odds = 1.0 * r**roll
另外,您不需要 Numpy(查看 random.choices
). There's also a Fraction
type provided in the standard library。
给定 10 次掷骰子,如果掷骰子是公平的,则您获得准确掷骰顺序的概率是 (1/6)**10
给定 10 卷已加载的骰子,您获得准确的掷骰顺序的概率是 (1/10)**(number of non-sixes) * (1/2) ** (number of sixes)
注意这两个值只是
math.product(p1[i - 1] for i in sequence)
math.product(p2[i - 1] for i in sequence)
鉴于两个骰子的先验概率是1:1,你可以比较这两个概率并选择最大的。