Моделирование по методу Монте-Карло дает 0 в качестве выходного

#python #statistics #montecarlo

Вопрос:

Я провел эксперимент, в ходе которого получил 6 различных порядков размера, и теперь пытаюсь понять, значимы ли мои наблюдения. Я должен выполнить моделирование MC, чтобы получить значение p, чтобы увидеть, являются ли мои наблюдаемые значения необычно большими или малыми по сравнению с нулем.

Мне необходимо:

  • Настройте схему, в которой порядок 1 равен от 0 до 1/6, Порядок 2 равен от 1/6 до 2/6, порядок 3 равен от 2/6 до 3/6
  • Сгенерируйте 20 случайных чисел в диапазоне от 0 до 1 и распределите их по этим ячейкам. Если число, если —

У меня должно быть 6 новых чисел, по одному для каждой ячейки, которые в сумме дают 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)
 

Комментарии:

1. В этом коде довольно много ошибок. counter = 1 не написано, и sim_orders = [0, 0, 0, 0, 0, 0] все они равны 0, и вы никогда не меняете их значение, так как это print(sim_orders) даст что-нибудь, кроме [0,0,0,0,0,0]

Ответ №1:

Вы не увеличиваете значения в sim_orders . Вы добавляете значение в sim_orders numbers , что не имеет никакого эффекта, потому что значение всегда 0 . И тогда вы ничего не делаете с numbers тем, что вы добавляете к нему.

Вам следует увеличить соответствующий счетчик sim_orders .

Вам нужно использовать random.random() , а не random.randint(0, 1) . Последнее просто вернет 0 или 1 , а не число между 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 последовательность взаимоисключающих условий, чтобы избежать ненужных тестов. И если вы сделаете это, вам не нужно проверять оба конца диапазона, так как предыдущий тест исключает числа ниже нижней части диапазона.

Ваши условия перекрывались-если numbers бы было точное число 1/6 , оно было бы помещено в обе ячейки.

Вы также можете полностью избавиться от всех if утверждений:

     sim_orders[floor(numbers*6)]  = 1
 

Комментарии:

1. Я попробовал это, но это только добавление чисел в позиции [0] и [5] sim_orders. Точка зрения элифа хороша, спасибо!

2. Потому что ты использовал randint вместо random

3. Ах, спасибо: это странно, потому что онлайн-гид посоветовал мне использовать randint! Еще один вопрос: как заставить мой код перестать выполняться, как только он достигнет 10 000 симуляций? В настоящее время это продолжается вечно

4. Ты никогда не увеличиваешься counter . Воспользуйся for counter in range(10000):

5. Вы уверены, что в онлайн-руководстве было показано, как генерировать числа от 0 до 1?

Ответ №2:

Если вы не хотите обновлять свой список sim_orders нулями, вам следует исключить его из цикла while. Более того, я не вижу, где вы обновляете свой список сгенерированными номерами. И если вы хотите, чтобы ваш цикл while был конечным, вам нужно увеличить счетчик внутри тела цикла.