matplotlib - 中心极限定理:样本均值不服从正态分布
问题描述
问题
晚上好。
我正在学习中心极限定理。作为练习,我进行了模拟以试图找到公平骰子的平均值(我知道,一个玩具问题)。
我拿了 4000 个样本,在每个样本中我掷骰子 50 次(底部的代码截图)。对于这 4000 个样本中的每一个,我计算了平均值。然后,我使用matplotlib
.
结果如下:
问题
鉴于 CLT 的条件(样本大小 >= 30)得到遵守,为什么样本均值不呈正态分布?
具体来说,为什么直方图看起来像两个叠加的正态分布?更有趣的是,为什么“外部”分布看起来“离散”,有规律的空间出现?
结果似乎以系统的方式关闭。
非常感谢所有帮助。我很失落。
补充代码
我用来生成 4000 个样本均值的代码。
"""
Take multiple samples of dice rolls. For
each sample, compute the sample mean.
With the sample means, plot a histogram.
By the Central Limit Theorem, the sample
means should be normally distributed.
"""
sample_means = []
num_samples = 4000
for i in range(num_samples):
# Large enough for CLT to hold
num_rolls = 50
sample = []
for j in range(num_rolls):
observation = random.randint(1, 6)
sample.append(observation)
sample_mean = sum(sample) / len(sample)
sample_means.append(sample_mean)
解决方案
当num_rolls
等于时50
,每个可能的均值都是带分母的分数50
。因此,实际上,您正在查看离散分布。
要创建离散分布的直方图,最好将 bin 边界放置在值之间。使用 的步长0.03
,一些 bin 边界将与值重合,将值的两倍放入一个 bin 与其相邻的 bin 相比。此外,由于微妙的浮点舍入问题,当值和边界重合时,结果可能变得不可预测。
下面是一些代码来说明发生了什么:
from matplotlib import pyplot as plt
import numpy as np
import random
sample_means = []
num_samples = 4000
for i in range(num_samples):
num_rolls = 50
sample = []
for j in range(num_rolls):
observation = random.randint(1, 6)
sample.append(observation)
sample_mean = sum(sample) / len(sample)
sample_means.append(sample_mean)
fig, axs = plt.subplots(2, 2, figsize=(14, 8))
random_y = np.random.rand(len(sample_means))
for (ax0, ax1), step in zip(axs, [0.03, 0.02]):
bins = np.arange(3.01, 4, step)
ax0.hist(sample_means, bins=bins)
ax0.set_title(f'step={step}')
ax0.vlines(bins, 0, ax0.get_ylim()[1], ls=':', color='r') # show the bin boundaries in red
ax1.scatter(sample_means, random_y, s=1) # show the sample means with a random y
ax1.vlines(bins, 0, 1, ls=':', color='r') # show the bin boundaries in red
ax1.set_xticks(np.arange(3, 4, 0.02))
ax1.set_xlim(3.0, 3.3) # zoom in to region to better see the ins
ax1.set_title('bin boundaries between values' if step == 0.02 else 'chaotic bin boundaries')
plt.show()
PS:请注意,如果不是 Python 列表,代码将运行得更快,代码将完全与 numpy 一起工作。