Wolfram和numpy对相同输入的标准差不同
我现在正在把一些用Java写的算法重新实现成Python。其中一个步骤是计算一组数值的标准差。原来的实现使用了Apache Math 1.1库中的DescriptiveStatistics.getStandardDeviation
。而我则使用了numpy 1.5中的标准差计算。问题是,对于相同的输入,它们给出的结果差别(很)大。我手头有的样本是这个:
[0.113967640255, 0.223095775796, 0.283134228235, 0.416793887842]
我得到的结果是:
numpy : 0.10932134388775223
Apache Math 1.1 : 0.12620366805397404
Wolfram Alpha : 0.12620366805397404
我还用Wolfram Alpha查了一下,想得到第三方的意见。我觉得这种差异不只是精度的问题。有没有人知道为什么会这样,以及我该怎么处理这个问题?
补充说明:我在Python中手动计算的结果是一样的:
>>> from math import sqrt
>>> v = [0.113967640255, 0.223095775796, 0.283134228235, 0.416793887842]
>>> mu = sum(v) / 4
>>> sqrt(sum([(x - mu)**2 for x in v]) / 4)
0.10932134388775223
还有,关于是不是用错了:
>>> from numpy import std
>>> std([0.113967640255, 0.223095775796, 0.283134228235, 0.416793887842])
0.10932134388775223
1 个回答
24
Apache和Wolfram在计算时用的是N-1而不是N。这是为了调整自由度,因为你在估算μ(总体均值)。用N-1来计算,可以得到一个不偏的总体标准差估计。你可以通过ddof
选项来改变NumPy的这种行为。
在NumPy的文档中有这样的说明:
平均平方偏差通常是通过x.sum() / N来计算的,这里的N是x的长度。如果指定了ddof,那么就会用N - ddof来作为除数。在标准统计实践中,ddof=1能提供一个不偏的无限总体方差估计。而ddof=0则是为正态分布变量提供一个最大似然估计的方差。这个函数计算的标准差是估计方差的平方根,所以即使ddof=1,它也并不是标准差本身的一个不偏估计。