Précision, pourquoi Matlab et Python numpy donnent-ils des sorties si différentes?

je connais les types de données de base et que les types float (float, double) ne peuvent pas contenir certains nombres exactement.

en transférant du code de Matlab à Python (Numpy), j'ai cependant trouvé des différences significatives dans les calculs, et je pense que cela revient à la précision.

prendre le code suivant, z-normaliser un vecteur de 500 dimensions avec seulement deux premiers éléments ayant un non-zéro valeur.

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
<!-En plus du fait que le formatage montre un peu plus de chiffres en Python, il y a une énorme différence (imho), plus de 0.02

Python et Matlab utilisent tous deux un type de données 64 bits (afaik). Python utilise ' numpy.float64 "et Matlab "double".

Pourquoi la différence si énorme? Laquelle est la plus correcte?

18
demandé sur rocksportrocker 2011-09-20 12:29:17

3 réponses

Peut-être que la différence vient de la mean et std appels. Comparez les d'abord.

il existe plusieurs définitions pour std, certains utilisent la racine sqaure de

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

d'autres utilisent

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

à la place.

D'un point mathématique: ces formules sont des estimateurs de la variance d'une variable aléatoire normale distribuée. La distribution a deux paramètres sigma et mu. Si vous connaissez mu exactement la estimateur optimal pour sigma ** 2

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

si vous devez estimer mu à partir de données à l'aide de mu = mean(xi), l'estimateur optimal pour sigma**2

1 / (n - 1) * sum((xi- mean(x))**2)
27
répondu rocksportrocker 2015-02-02 16:18:55

pour répondre À ta question, aucun, ce n'est pas un problème de précision. @rocksportrocker, il y a des deux estimateurs pour l'écart-type. MATLAB's std a les deux disponibles mais en standard utilise un différent de ce que vous avez utilisé en Python.

std(Z,1) au lieu de std(Z):

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

mène à

Za (1) = 21.1905669677

dans MATLAB. Lire rockspotrocker réponse sur laquelle des deux résultats est plus approprié pour ce que vous voulez faire ;-).

14
répondu Jonas Heidelberg 2017-05-23 12:33:57

selon la documentation de stdSciPy, il a un paramètre appelé ddof:

ddof: int, en option

Signifie Delta degrés de liberté. Le diviseur utilisé dans les calculs est n-ddof, où n représente le nombre d'éléments. Par défaut ddof est zéro.

Dans numpy, ddof est zéro par défaut alors que dans MATLAB est un. Donc, je pense que cela pourrait résoudre le problème:

std(Z,ddof=1)
3
répondu cartoonist 2014-01-03 19:03:00