我尝试将matlab代码转换为numpy,并发现numpy与std函数有不同的结果。为什么numpy std()给matlab std()提供了一个不同的结果?
在MATLAB
std([1,3,4,6])
ans = 2.0817
在numpy的
np.std([1,3,4,6])
1.8027756377319946
这是正常的吗?我应该如何处理这个问题?
我尝试将matlab代码转换为numpy,并发现numpy与std函数有不同的结果。为什么numpy std()给matlab std()提供了一个不同的结果?
在MATLAB
std([1,3,4,6])
ans = 2.0817
在numpy的
np.std([1,3,4,6])
1.8027756377319946
这是正常的吗?我应该如何处理这个问题?
NumPy函数np.std
采用可选参数ddof
:“Delta自由度”。默认情况下,这是0
。将它设置为1
获得MATLAB结果:
>>> np.std([1,3,4,6], ddof=1)
2.0816659994661326
要添加多一点的背景下,方差(其中标准偏差的平方根)的计算,我们通常是通过值的数量除以我们有。
但是,如果我们从较大的分布中选择N
元素的随机样本并计算方差,则除以N
可能会导致低估实际方差。为了解决这个问题,我们可以将我们除以(the degrees of freedom)的数字降低到小于N
(通常为N-1
)的数字。 ddof
参数允许我们按照指定的数量更改除数。
除非特别指出,NumPy的将计算偏置估计器,用于方差(ddof=0
,由N
分割)。如果您使用整个分布(而不是从较大分布中随机挑选的值的子集),那么这就是您想要的。如果给出ddof
参数,则NumPy将被N - ddof
分隔。
MATLAB的std
的默认行为是通过除以N-1
来纠正样本方差的偏差。这消除了标准偏差中的一些(但可能不是全部)偏差。如果您在大型分布的随机样本上使用该函数,这很可能就是您想要的。
@hbaderts的好答案给出了进一步的数学细节。
标准偏差是方差的平方根。的随机变量X
方差被定义为
为方差估计器将因此会
其中表示样本平均值。对于随机选择
,可以表明这种估计不收敛于真实的差异,但
如果你随机抽取样品,并估计样本均值和方差,你将不得不使用校正(无偏)估计
这将收敛于。校正项
也被称为贝塞尔校正。
现在在默认情况下,MATLABs std
计算无偏估计与修正项n-1
。然而,NumPy(如@ajcr解释)计算偏差估计量,默认情况下没有校正项。参数ddof
允许设置任何修正术语n-ddof
。通过设置为1,您可以得到与MATLAB相同的结果。
同样,MATLAB允许添加第二个参数w
,它指定了“称重方案”。默认值w=0
导致校正项n-1
(无偏估计量),而对于w=1
,仅将n用作校正项(偏差估计量)。
在修正估计量的公式中,因子* n *(在和内)不应该存在。 – Frunobulax
方差中n-1项的直觉:你已经使用你的样本来估计你将用于逼近方差的平均值。这引入了一个相关性,因此ddof必须是1. – Matthias
@Frunobulax我修复了后缀错误。原始方程中发生的事情是,总和的上限未被正确渲染。它不是在总和符号的顶部,而是在总和内。 – rayryeng
的人谁不伟大的统计,一个简单的指南:
包括ddof=1
如果你计算np.std()
从您的完整数据集取样。
确保ddof=0
如果你的DDOF是为了抵消可能出现的数字偏差包括样品全部人口
计算np.std()
。
我会在Matlab中加入'std([1 3 4 6],1)'相当于NumPy默认的'np.std([1,3,4,6])''。所有这些在Matlab和NumPy的文档中都有相当清楚的解释,所以我强烈建议OP将来一定要阅读这些内容。 – horchler