c

codeye

V1

2022/09/22阅读:14主题:默认主题

正态分布

import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
import seaborn as sns

现在我们来生成一些数据。我们将假设一个人的真实平均身高是5英尺6英寸,真实标准差是1英尺(12英寸)。我们还定义了一个名为 "目标 "的变量,即6英尺,这是我们朋友询问的身高。为了使生活更容易,我们将把所有的东西转换为英寸。


Mean_height = 5.5*12
stdev_height = 1*12
target = 6*12

有了这些参数,我们现在可以制作一些高度数据。我们将制作一个10,000乘以10的数组来保存我们的调查结果,其中每一行是一个调查。然后我们将用一个正态分布的随机变量来填充数组的每个元素。你可以给随机变量函数一个平均值和一个标准差,但我想告诉你如何手动定制随机变量的平均值和标准差(更直观)。

你可以通过向你的正态分布随机变量添加一个常数来移动平均数(其中常数是你想要的平均数)。它将随机变量的中心位置从0改为你添加的任何数字。 你可以通过向你的随机变量乘以一个常数来修改正态分布随机变量的标准差(其中常数是你希望的标准差)。

在下面的代码中,np.random.normal()生成了一个平均数为0、标准差为1的正态分布的随机数,然后我们用它乘以 "stdev_height",得到我们想要的12英寸的波动率,再加上 "mean_height",以便将中心位置移动66英寸。

Mean_height + np.random.normal()*stdev_height

我们可以使用嵌套for循环来填写我们的调查数据,然后检查输出是否符合我们的期望。

height_surveys = np.zeros((10000,10))
for i in range(height_surveys.shape[0]):
    for j in range(height_surveys.shape[1]):
        height_surveys[i,j] = mean_height +\
                              np.random.normal()*stdev_height
print('Mean Height:', round(np.mean(height_surveys)/12,1), 'feet')
print('Standard Deviation of Height:'
      round(np.var(height_surveys)**0.5/12,1), 'foot')

当我运行这段代码时,它打印出平均身高是5.5英尺,人们身高的标准偏差是1英尺--这些与我们的输入相吻合。好的,我们有了我们的调查数据。现在让我们做一些统计推理。

假设我们只有时间和资源来进行一次身高调查(10个人)。而我们得到了以下结果。

单次调查柱状图 一半人的身高超过6英尺,一半人的身高较短(红线表示6英尺)--信息量不大。我们样本中的平均身高是69英寸,略低于6英尺。

尽管如此,我们还是要记住,因为我们的样本量很小(调查中只有10个人),我们应该预期我们的结果会有很多差异。最酷的是,即使只有一次调查,我们也可以对平均值的变化程度有一个相当不错的估计。而且我们知道分布的形状--它是正态分布(铁杆统计学家会说我需要说它是大致的正态分布)!这就是我们的标准误差。

标准误差=样本标准偏差/sqrt(N)

其中N是观察值的数量(在我们的例子中是10),sqrt表示取平方根。

标准误差是平均值的标准偏差(如果我们一直进行10个人的调查,并从每个人身上计算出一个平均值,这些平均值的标准偏差最终会收敛到标准误差)。就像我们提到的,样本平均值的分布是正态分布。意思是说,如果我们要进行大量的调查,并在总体上看他们各自的平均值,我们会期望看到一个钟形曲线。让我们来看看这个。

回顾一下,早些时候我们创建了一个10,000乘10的调查结果数组。我们的10,000行中的每一行都是一项调查。让我们计算出10,000份调查的平均值,并通过以下几行代码绘制直方图。

显示所有调查的平均值分布的直方图

# Histogram that shows the distribution for the mean of all surveys
fig, ax = plt.subplots(figsize=(12,8))
sns.distplot(np.mean(height_surveys,axis=1), 
             kde=False, label='Height')
ax.set_xlabel("Height in Inches",fontsize=16)
ax.set_ylabel("Frequency",fontsize=16)
plt.axvline(target, color='red')
plt.legend()
plt.tight_layout()

这样我们就得到了下面的直方图--如果我看到过的话,这就是一条钟形曲线。

样本平均数的直方图 现在让我们只用我们的原始调查(我展示的第一个看起来很古怪的直方图)来计算分布。由于只有一个10人的样本,我们别无选择,只能将样本平均数猜测为真正的平均数(即统计学中所说的群体平均数)。因此,我们将猜测平均值为69英寸。

现在我们来计算一下标准误差。我们样本的标准差是12.5英寸。

我随机挑选了35号样本来绘制早些时候的图表

np.var(height_surveys[35])**0.5) # = 12.5 让我们把我们的推断分布,即平均数为69英寸、标准差为12.5英寸的正态分布叠加到真实分布上(来自我们的10,000个模拟调查,我们假设它是地面真相)。我们可以通过以下几行代码来做到这一点,其中

比较所有调查的平均值和推断的分布

fig, ax = plt.subplots(figsize=(12,8))

绘制10,000个样本平均值的直方图

sns.distplot(np.mean(height_surveys,axis=1), kde=False, label='True')

使用单个样本计算统计数字

sample_mean = np.mean(height_surveys[35]) sample_stdev = np.var(height_surveys[35])**0.5

计算标准误差

std_error = sample_stdev/(height_surveys[35].shape[0])**0.5

使用单个样本推断分布

inferred_dist = [sample_mean + np.random.normal()*. std_error for i in range(10000)]

绘制推断分布的柱状图

sns.distplot(inferred_dist, kde=False, label='推断', color='red') ax.set_xlabel("Height in Inches",fonttsize=16) ax.set_ylabel("频率",字体大小=16) plt.legend() plt.tight_layout() 然后我们得到以下一组柱状图。

我们有些偏差,但说实话,考虑到我们只用10个观测值就生成了推断的分布(红色),这还不算太糟糕。而我们能够做到这一点,要归功于样本平均数的分布是正态分布这一事实。

我们对标准差的估计也有方差 对于好奇的人来说,样本标准差的分布也大致是正态的(这里的样本标准差是对10个人进行的一次调查的标准差)。

分类:

后端

标签:

后端

作者介绍

c
codeye
V1