我可以将 numpy.std() 应用于什么?

What can I apply numpy.std() to?

我对统计知识知之甚少,所以请原谅我,但我对 numpy 函数 std 的工作原理感到很困惑,不幸的是,文档没有对此进行清理。

据我了解,它将计算数组分布的标准差,但是当我使用以下代码设置标准差为 0.5 的高斯分布时,numpy.std returns 0.2:

sigma = 0.5
mu = 1
x = np.linspace(0, 2, 100)
f = (1 / (sigma * np.sqrt(2 * np.pi))) * np.exp((-1 / 2) * ((x - mu) / sigma)**2)
plt.plot(x, f)
plt.show()
print(np.std(f))

这是分布:

我不知道我对函数的工作原理有什么误解。我想也许我必须告诉它与分布的 y 值相关联的 x 值,但在函数中没有参数。为什么 numpy.std 没有返回我的分布的实际标准偏差?

np.std 用于计算标准偏差。这可以按以下步骤计算

  1. 首先我们需要计算分布均值
  2. 然后求和(x - x.mean)**2
  3. 然后求出上述求和的均值(除以分布中的元素个数)
  4. 然后求此均值的平方根(在第 3 步中计算)。

因此该函数正在计算传递给它的分布的标准差。

我怀疑您完全理解函数的工作原理,但误解了数据的含义。标准偏差是衡量数据关于平均值的分布。

当您说 std(f) 时,您计算的是 y-values 均值的分布。查看问题中的图表,~0.5 的垂直平均值和~0.2 的标准偏差并不遥远。请注意 std(f) 不以任何方式涉及 x-values。

您期望得到的是 x-values 的标准偏差,由 y-values 加权。这本质上是概率密度函数 (PDF) 背后的思想。

让我们手动完成计算以了解差异。 x-values 的平均值通常是 x.sum() / x.size。但只有每个值的权重为 1 时才成立。如果用相应的 f 值对每个值进行加权,则可以写成

m = (x * f).sum() / f.sum()

标准差是 root-mean-square 的平均值。这意味着计算与平均值的平均平方偏差,并取平方根。我们可以用与之前完全相同的方式计算平方偏差的加权平均值:

 s = np.sqrt(np.sum((x - m)**2 * f) / f.sum())

请注意,根据您的问题以这种方式计算的 s 的值不是 0.5,而是 0.44。这是因为您的 PDF 不完整,缺少尾部会显着增加传播。

这是一个示例,表明当您为更大的 PDF 样本计算标准差时,标准差会收敛到预期值:

>>> def s(x, y):
...     m = (x * y).sum() / y.sum()
...     return np.sqrt(np.sum((x - m)**2 * y) / y.sum())

>>> sigma = 0.5

>>> x1 = np.linspace(-1, 1, 100)
>>> y1 = (1 / (sigma * np.sqrt(2 * np.pi))) * np.exp(-0.5 * (x1 / sigma)**2)
>>> s(x1, y1)
0.4418881290522094

>>> x2 = np.linspace(-2, 2, 100)
>>> y2 = (1 / (sigma * np.sqrt(2 * np.pi))) * np.exp(-0.5 * (x2 / sigma)**2)
>>> s(x2, y2)
0.49977093783005005

>>> x3 = np.linspace(-3, 3, 100)
>>> y3 = (1 / (sigma * np.sqrt(2 * np.pi))) * np.exp(-0.5 * (x3 / sigma)**2)
>>> s(x3, y3)
0.49999998748515206