Распределение результатов в экспериментах с костями - PullRequest
3 голосов
/ 17 июня 2020

Итак, я написал короткую функцию Python для построения графика распределения результатов экспериментов с игральными костями. Он работает нормально, но когда я запускаю, например, dice(1,5000) или dice(10,5000) или dice(100,5000), гистограммы показывают искаженное распределение (высокое предпочтение для 6). Однако среднее значение показывает ожидаемое значение около 3.5. Я подумал, что, возможно, это связано с генерацией случайных чисел, поэтому я попробовал 2 метода: 1-й с random.randint, а 2-й - как в коде. Однако они дают аналогичные результаты. Как будто что-то не так с верхним пределом. Но я не уверен, почему существует такой перекос.

import matplotlib.pyplot as plt
import numpy as np
import random

# Throw a dice
def dice(N,n):
    result = np.zeros((n,N))
    '''
    N: number of dices
    n: number of experiment
    '''
    for i in range(n):
        for j in range(N):
            random_number = random.random()
            outcome = int(random_number * 6 + 1)
            result[i][j]=outcome
    laverage = np.mean(result)

    print('Result of throwing %d dice(s) for %d times:'%(N,n),result)
    print(laverage)
    plt.hist(np.resize(result,(N*n,1)),bins=[x for x in range(1,7)])
    plt.xlabel('Outcome')
    plt.ylabel('Number of occurences')
    plt.show()

dice(1,5000)

Ответы [ 3 ]

5 голосов
/ 17 июня 2020

Ваш график показывает только 5 полосок - полоса справа от числа, поэтому я считаю, что результаты для 5 и 6 объединяются. Если вы измените значение на range(1,8), вы увидите больше ожидаемого.

enter image description here

3 голосов
/ 17 июня 2020

Согласно образцу вашего кода, проблема заключается в проблеме построения графика, а не в вычислениях, поэтому вы видите правильное среднее значение. Как вы можете видеть, на следующем изображении показаны пять полосок, последняя из которых в два раза больше остальных:

pic

Обратите внимание, что полосы обозначены слева, поэтому полоски «6» нет. Это связано с тем, что plt.hist означает bins:

Если бины является последовательностью, она определяет края бункера, включая левый край первого бункера и правый край последнего бункера; в этом случае интервалы могут быть расположены неравномерно. Все, кроме последнего (самого правого) бункера, наполовину открыты. 1023 *

enter image description here

незаданные вопросы

Если вы хотите смоделировать N * n точек данных, вы можете использовать numpy напрямую. Замените исходную инициализацию result и for l oop любой из следующих строк:

result = (np.random.uniform(size=(n, N)) * 6 + 1).astype(int)
result = np.random.uniform(1.0. 7.0, size=(n, N)).astype(int)
result = np.random.randint(1, 7, size=(n, N))

Последняя строка предпочтительнее с точки зрения эффективности и точности.

Еще одно возможное улучшение - это способ вычисления гистограммы. Прямо сейчас вы используете plt.hist, который вызывает np.histogram и plt.bar. Для небольших целых чисел, таких как у вас, np.bincount, возможно, гораздо лучший метод биннинга:

count = np.bincount(result.ravel())[1:]
plt.bar(np.arange(1, 7), count)

Обратите внимание, что это также упрощает построение, поскольку вы напрямую указываете центры полос, вместо plt.hist угадайте.

1 голос
/ 17 июня 2020

Если вы ленивы (как я), вы также можете использовать numpy для непосредственного создания матрицы и seaborn для работы с бункерами для вас:

import numpy as np
import seaborn as sns

dices = 1000
throws = 5000
x = np.random.randint(6, size=(dices, throws)) + 1
sns.distplot(x)

Что дает :

enter image description here

Seaborn обычно делает хороший выбор, что позволяет сэкономить немного времени при настройке. По крайней мере, это стоит попробовать. Вы также можете использовать опцию kde=False на морском графике, чтобы избавиться от оценки плотности.

Просто ради и для того, чтобы показать, как ведут себя морские волки, то же самое с суммой более 100 кубиков:

dices = 100
throws = 5000
x = np.random.randint(6, size=(dices, throws)) + 1
sns.distplot(x.sum(axis=0), kde=False)

enter image description here

...