两个骰子的朴素贝叶斯方法

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,你可以比较这两个概率并选择最大的。