骰子实验的结果分布

问题描述 投票:1回答:1

所以我写了一个简短的Python函数来绘制骰子实验的分布结果。它运行得很好,但是当我运行例如 dice(1,5000)dice(10,5000)dice(100,5000) 直方图显示出倾斜分布(高度偏重于6)。然而,平均数显示的是即将到来的预期值,约为6。3.5. 我想这可能与随机数的产生有关,所以我尝试了2种方法:第一种是用 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)
python histogram distribution
1个回答
5
投票

你的图只显示了5个条形图--条形图在数字的右边,所以我相信结果为 56 正在合并。如果你改成 range(1,8) 你看到的更多是你所期望的。

enter image description here


2
投票

根据您的代码样本,问题是绘图问题,而不是计算问题,这就是为什么您看到的是正确的平均值。正如你所看到的,下图显示了五个条形图,最后一个是其他条形图的两倍。

pic

还请注意,这些条形图是标在左边的,因此没有 "6 "条。这与以下几点有关 plt.hist 手段 bins:

如果: 箱子 是一个序列,它定义了料仓的边缘,包括第一个料仓的左边缘和最后一个料仓的右边缘;在这种情况下,料仓可能是不等距的。除了最后一个(最右端)bin之外,所有bin都是半开的。

因此,要指定料仓边缘,你可能需要更多的东西,如

plt.hist(np.ravel(result), bins=np.arange(0.5, 7.5, 1))

而结果呢?

enter image description here

未问的问题

如果你想模拟 N * n 数据点,你可以直接使用numpy。替换你原来初始化的 resultfor 循环中的任何一行。

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.histogramplt.bar. 对于像你这样的小整数。np.bincount 可以说是一种更好的分层技术。

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

请注意,这也简化了绘图,因为你直接指定了条形图的中心,而不是要用 plt.hist 为你猜测。


1
投票

如果你很懒(比如我),你也可以用numpy直接生成一个矩阵和 海底 为你处理垃圾箱。

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 选项来消除密度估计。

只是为了展示seaborn的表现,同样的,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

© www.soinside.com 2019 - 2024. All rights reserved.