【问题标题】:Monte Carlo Simulation giving 0 as output蒙特卡洛模拟给出 0 作为输出
【发布时间】:2021-06-28 08:45:48
【问题描述】:

我进行了一项实验,其中我得到了 6 个不同数量级的大小,现在我想看看我的观察是否有意义。我必须执行 MC 模拟以获得 p 值,以查看我的观察值与 null 相比是异常大还是异常小。

我需要:

  • 设置顺序 1 为 0 到 1/6,顺序 2 为 1/6- 到 2/6,顺序 3 为 2/6 到 3/6 的方案
  • 生成 20 个介于 0 和 1 之间的随机数并将它们分配给这些 bin。如果数字 if

我应该有 6 个新数字,每个 bin 一个,加起来是 20,但我的输出是 0。我是 python 新手,我做错了什么?

我的代码在这里:

from random import randint
from random import seed

# seed random number generator
seed(1)
counter = 0
chi_sq_values = []
# want 10,000 simulations
while counter < 10000:
    # will eventually mimic your real six orders of size
    sim_orders = [0, 0, 0, 0, 0, 0]
    # generating 20 random numbers
    for i in range(20):
        numbers = randint(0, 1)
        if 0 <= numbers <= 1 / 6:
            numbers += sim_orders[0]
        if 1 / 6 <= numbers <= 2 / 6:
            numbers += sim_orders[1]
        if 2 / 6 <= numbers <= 3 / 6:
            numbers += sim_orders[2]
        if 3 / 6 <= numbers <= 4 / 6:
            numbers += sim_orders[3]
        if 4 / 6 <= numbers <= 5 / 6:
            numbers += sim_orders[4]
        if 5 / 6 <= numbers <= 6 / 6:
            numbers += sim_orders[5]

    print(sim_orders)

【问题讨论】:

  • 这段代码有很多地方是错误的。 counter += 1 没有被写入,sim_orders = [0, 0, 0, 0, 0, 0] 它们都是 0,而且你永远不会改变它们的值,那么 print(sim_orders) 将如何提供除了 [0,0,0,0,0,0] 之外的任何东西

标签: python statistics montecarlo


【解决方案1】:

如果你不想用零更新你的列表sim_orders,那么你应该把它out of while循环。此外,我看不到您在哪里使用生成的数字更新列表。如果你希望你的 while 循环是有限的,那么你必须在循环体内增加计数器。

【讨论】:

    【解决方案2】:

    您没有增加sim_orders 中的值。您将sim_orders 中的值添加到numbers,这没有任何效果,因为该值始终为0。然后你添加到 numbers 之后就什么也不做了。

    您应该在sim_orders 中增加相应的计数器。

    您需要使用random.random(),而不是random.randint(0, 1)。后者只会返回 01,而不是 0 到 1 之间的数字。

        for i in range(20):
            numbers = random.random()
            if numbers <= 1 / 6:
                sim_orders[0] += 1
            elif numbers <= 2 / 6:
                sim_orders[1] += 1
            elif numbers <= 3 / 6:
                sim_orders[2] += 1
            elif numbers <= 4 / 6:
                sim_orders[3] += 1
            elif numbers <= 5 / 6:
                sim_orders[4] += 1
            else:
                sim_orders[5] += 1
    

    您还应该将elif 用于一系列互斥条件,以避免不必要的测试。如果这样做,则不需要测试范围的两端,因为之前的测试排除了低于范围底部的数字。

    您的条件重叠 - 如果 numbers1/6 的精确倍数,它将被放入两个箱中。

    您还可以完全摆脱所有 if 语句:

        sim_orders[floor(numbers*6)] += 1
    

    【讨论】:

    • 我试过这个,但它只是将数字添加到 sim_orders 的 [0] 和 [5] 位置。 elif 点很好,谢谢!
    • 因为你使用了randint 而不是random
    • 啊,谢谢:这很奇怪,因为在线指南告诉我使用 randint!另一个问题:如何让我的代码在达到 10,000 次模拟后停止运行?它目前一直持续下去
    • 你永远不会增加counter。使用for counter in range(10000):
    • 您确定在线指南显示了如何生成 0 和 1 之间的数字吗?
    猜你喜欢
    • 2021-01-06
    • 1970-01-01
    • 2014-12-09
    • 2018-09-24
    • 2018-04-03
    • 2018-07-21
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    相关资源
    最近更新 更多