【问题标题】:Naive Bayes method for two dice两个骰子的朴素贝叶斯方法
【发布时间】:2021-02-28 22:19:05
【问题描述】:

我需要帮助实现两个骰子的朴素贝叶斯方法 - 其中一个是具有六个面的“正常”骰子,因此每个面出现1/6 的概率相同。另一个是加载的骰子,每次尝试都会给出6 的结果。

我的程序应该输入骰子的选择,然后模拟十个掷骰的序列。

我必须从赔率1:1 开始,然后在每个结果之后应用朴素贝叶斯方法更新赔率,以决定选择哪个骰子(最有可能)。如果最有可能的骰子是加载的骰子,它应该返回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 的情况,但不幸的是代码不能正常工作。你能帮帮我吗?

【问题讨论】:

    标签: python naivebayes


    【解决方案1】:
    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)。还有a Fraction type provided in the standard library

    【讨论】:

    • 你是这个意思吗?对于范围内的 i(len(p1)): r = p1[i]/p2[i] 如果 r == 10/6: 赔率 = 1.0*r**(roll) elif r == 1/3: 赔率 = 1.0*r**(滚动)。还是不行。
    • “无论如何都没有理由执行此条件检查”的哪一部分不清楚?您的代码不应在其中包含ifelif,因为您的代码不关心 r 的具体值。发生该错误是因为您期望与浮点数进行精确比较,而浮点数不能那样工作,正如我已经明确告诉您的那样,并提供了解释的链接。如果您不阅读,我无法帮助您。
    • 我尝试了各种情况,但仍然没有通过测试(很遗憾,但可能存在错误)。将尝试修复它。非常感谢,无论如何! PS。我读了你的建议。
    【解决方案2】:

    给定 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,您只需比较这两个概率并选择最大的。

    【讨论】:

    • 我试过这个: for i in range(len(p1)): odds = math.prod(p1[i - 1] for i in sequence) for i in range(len(p2)) :赔率 = math.prod(p2[i - 1] for i in sequence)。而且它不起作用。
    • 我很困惑。你有一个双循环。你为什么做这个?如果您还有(.... for i in sequence),则不需要外部for i in range(len(p1))
    • 它在什么方面不适合你。我刚刚尝试了一些测试,它在 100 次测试中做出了 87 次正确判断
    • 我尝试使用两个 for 循环来区分赔率。好吧,测试给出了像 True != False 或 False != True 这样的错误。
    • 你不会得到 100%。随机骰子看起来是装满的,而装满的骰子看起来是随机的。我能猜对 90% 的时间。
    猜你喜欢
    • 2018-02-14
    • 2012-02-21
    • 2011-12-28
    • 2013-09-09
    • 2015-01-03
    • 2017-02-09
    • 2012-09-23
    • 2021-09-14
    • 2016-08-25
    相关资源
    最近更新 更多