18

我知道基本数据类型,浮点类型(float,double)不能准确地保存一些数字。

然而,在将一些代码从 Matlab 移植到 Python (Numpy) 时,我发现计算上有一些显着差异,我认为它会回到精确度。

使用以下代码,对 500 维向量进行 z 归一化,其中只有前两个元素具有非零值。

MATLAB:

Z = repmat(0,500,1); Z(1)=3;Z(2)=1;
Za = (Z-repmat(mean(Z),500,1)) ./ repmat(std(Z),500,1);
Za(1)
>>> 21.1694

Python:

from numpy import zeros,mean,std
Z = zeros((500,))
Z[0] = 3
Z[1] = 1
Za = (Z - mean(Z)) / std(Z)
print Za[0]
>>> 21.1905669677

除了格式在 Python 中显示更多的数字之外,还有一个巨大的差异(恕我直言),超过 0.02

Python 和 Matlab 都使用 64 位数据类型 (afaik)。Python 使用 'numpy.float64' 和 Matlab 'double'。

为什么差异如此之大?哪一个更正确?

4

3 回答 3

27

也许差异来自meanandstd调用。先比较一下。

有几种定义std,有些使用平方根

1 / n * sum((xi - mean(x)) ** 2)

其他人使用

1 / (n - 1) * sum((xi - mean(x)) ** 2)

反而。

从数学角度来看:这些公式是对正态分布随机变量方差的估计。分布有两个参数sigmamu。如果您mu确切知道最佳估计量sigma ** 2

1 / n * sum((xi - mu) ** 2)

如果您必须mu使用 的数据进行mu = mean(xi)估计,则最佳估计量sigma**2

1 / (n - 1) * sum((xi- mean(x))**2)
于 2011-09-20T08:46:44.467 回答
14

要回答您的问题,,这不是精度问题。正如@rocksportrocker指出的那样,标准差有两个流行的估计器。MATLABstd两者都可用,但作为标准使用的标准与您在 Python 中使用的不同。

尝试std(Z,1)代替std(Z)

Za = (Z-repmat(mean(Z),500,1)) ./ repmat(std(Z,2),500,1);Za(1)
sprintf('%1.10f', Za(1))

导致

Za(1) = 21.1905669677

在 MATLAB 中。阅读 rockpotrocker 的回答,了解这两个结果中哪一个更适合您想要做的事情;-)。

于 2011-09-20T08:46:29.697 回答
3

根据stdat SciPy的文档,它有一个名为ddof

ddof : int, optional
表示 Delta 自由度。计算中使用的除数是 N - ddof,其中 N 表示元素的数量。默认情况下 ddof 为零。

在 numpy 中,ddof默认为零,而在 MATLAB 中为一。所以,我认为这可以解决问题:

std(Z,ddof=1)
于 2014-01-03T16:46:10.460 回答