Python SciPy-Bernoulli随机数生成,不同样本大小的for循环中的不同行为
本代码的目的是演示CLT 如果我这样做:Python SciPy-Bernoulli随机数生成,不同样本大小的for循环中的不同行为,python,matplotlib,scipy,statistics,Python,Matplotlib,Scipy,Statistics,本代码的目的是演示CLT 如果我这样做: num_samples = 10000 sample_means = np.empty(num_samples) for i in range(num_samples): mean = np.mean(st.bernoulli.rvs(p=0.5, size=100)) sample_means[i] = mean sample_demeaned = np.subtract(sample_means, 0.5) denominator = n
num_samples = 10000
sample_means = np.empty(num_samples)
for i in range(num_samples):
mean = np.mean(st.bernoulli.rvs(p=0.5, size=100))
sample_means[i] = mean
sample_demeaned = np.subtract(sample_means, 0.5)
denominator = np.divide(0.5, np.sqrt(100))
z_ed = np.divide(sample_demeaned, denominator)
plt.hist(z_ed, bins=40, edgecolor='k', density=True)
x = np.linspace(st.norm.ppf(0.001), st.norm.ppf(0.999), 10000)
y = st.norm.pdf(x)
plt.plot(x, y, color='red')
我得到:
但是,如果我尝试对不同的样本大小使用for循环:
num_samples = 10000
sample_sizes = np.array([5, 20, 75, 100])
sample_std_means = np.empty(shape=(num_samples, len(sample_sizes)))
for col, size in enumerate(sample_sizes):
sample_means = np.empty(num_samples)
for i in range(num_samples):
mean = np.mean(st.bernoulli.rvs(p=0.5, size=size))
sample_means[i] = mean
sample_demeaned = np.subtract(sample_means, 0.5)
denominator = np.divide(0.5, np.sqrt(size))
z_ed = np.divide(sample_demeaned, denominator)
sample_std_means[:, col] = sample_means
然后在2x2网格中绘制它们:
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 7))
x = np.linspace(st.norm.ppf(0.001), st.norm.ppf(0.999), 10000)
y = st.norm.pdf(x)
for i, ax in enumerate(axes.flatten()):
ax.hist(sample_std_means[i], bins=40, edgecolor='k', color='midnightblue')
ax.set_ylabel('Density')
ax.set_xlabel(f'n = {sample_sizes[i]}')
ax.plot(x, y, color='red')
ax.set_xlim((-3, 3))
plt.show()
我得到以下图像:
我无法在这里调试差异。非常感谢您的帮助
请注意,scipy.stats和numpy在这两个代码块中分别作为st和np导入。首先,请注意,numpy的优点是它允许混合数组和单个数字的操作。这就是所谓的。因此,例如
sample\u demened=np.subtract(sample\u表示0.5)
可以写得更简洁,因为sample\u demened=sample\u表示-0.5
有几个问题出了问题:
应使用刚刚计算的sample\u std\u means[:,col]=sample\u means
而不是z\u ed
sample\u means
使用数组的第i行。该行仅包含4个元素。您希望ax.hist(sample\u std\u表示[i],…)
占据第i列sample\u std_means[;i]
- pdf以其规范化形式绘制(曲线下方的面积等于1)。但是,直方图的高度与样本数成正比。其总面积为
,其中直方图的默认bin width是从第一个元素到最后一个元素的长度除以bin的数量。要获得大小相似的pdf和直方图,要么对直方图进行归一化(使用num_samples*bin_width
),要么将pdf乘以直方图的预期面积density=True
将numpy导入为np
将scipy.stats导入为st
将matplotlib.pyplot作为plt导入
样本数=10000
样本大小=np.数组([5,20,75,100])
样本标准表示为np.empty(形状=(样本数量,长度(样本大小)))
对于列,枚举中的大小(样本大小):
样本_意味着=np.empty(num_样本)
对于范围内的i(num_样本):
样本_表示[i]=np.平均值(圣伯努利rvs(p=0.5,尺寸=尺寸))
样本_demeaned=样本_表示-0.5
z_ed=样品尺寸/(0.5/np.sqrt(尺寸))
样本标准表示[:,列]=z
图,轴=plt.子批次(nrows=2,ncols=2,figsize=(10,7))
x=np.linspace(标准规范ppf(0.001),标准规范ppf(0.999),1000)
y=st.norm.pdf(x)
对于i,枚举中的ax(axs.flatte()):
ax.hist(样本标准是指[:,i],箱=40,边色=k,颜色=午夜蓝,密度=True)
ax.set_ylabel('密度')
ax.set_xlabel(f'n={sample_size[i]}')
#bin_width=(sample_std_表示[:,i].max()-sample_std_表示[:,i].min())/40
#ax.plot(x,y*num\u samples*bin\u width,color='red')
ax.绘图(x,y,color='red')
ax.set_xlim(-3,3))
plt.show()
现在注意直方图中奇怪的空条。直方图最适用于连续分布。但是n
Bernoulli试验的平均值最多可以有n+1
不同的结果。当所有试验均为真时,平均值为n/n=1
。当all为False时,平均值为0
。结合起来,可能的方法是0,1/n,2/n,…,1
。这种离散分布的直方图应将这些值考虑到料仓之间的边界
下面的代码创建散点图,使用平均值的位置和随机y值来可视化每个x有多少个。此外,通过垂直虚线计算并显示箱子边界的位置
fig,axes=plt.子批次(nrows=2,ncols=2,figsize=(10,7))
对于i,枚举中的ax(axs.flatte()):
最大散射(样本标准表示[:,i],np.随机.均匀(0,1,数量样本),颜色=r',α=0.5,lw=0,s=1)
#n个伯努利试验有n+1个可能的平均值
#需要n+2个边界来分隔垃圾箱
箱子=np.arange(-1,样本大小[i]+1)/样本大小[i]
箱子+=(箱子[1]-箱子[0])/2#移动半个箱子
bins-=0.5#减去平均值
bins/=(0.5/np.sqrt(样本量[i])校正系数
对于垃圾箱中的b:
ax.axvline(b,color='g',ls=':')
ax.set_xlabel(f'n={sample_size[i]}')
ax.set_xlim(-3,3))
以下是使用这些箱子的直方图:
ax.hist(样本标准表示[:,i],容器=容器,边缘颜色为k',颜色为午夜蓝色,密度为真)
这是否回答了您的问题?如果这回答了你的问题,你可能会考虑投票和/或答案。