web-dev-qa-db-fra.com

Pourquoi numpy std () donne-t-il un résultat différent de matlab std ()?

J'essaie de convertir le code matlab en numpy et j'ai compris que numpy avait un résultat différent avec la fonction std.

dans matlab

std([1,3,4,6])
ans =  2.0817

en numpy

np.std([1,3,4,6])
1.8027756377319946

Est-ce normal? Et comment devrais-je gérer cela?

79
gustavgans

La fonction NumPy np.std prend un paramètre optionnel ddof: "Delta Degrees of Freedom". Par défaut, c'est 0. Réglez-le sur 1 pour obtenir le résultat MATLAB:

>>> np.std([1,3,4,6], ddof=1)
2.0816659994661326

Pour ajouter un peu plus de contexte, dans le calcul de la variance (dont l’écart-type est la racine carrée), nous divisons généralement par le nombre de valeurs que nous avons.

Mais si nous sélectionnons un échantillon aléatoire de N éléments d'une distribution plus large et calculons la variance, la division par N peut entraîner une sous-estimation de la variance réelle. Pour résoudre ce problème, nous pouvons réduire le nombre que nous divisons par ( les degrés de liberté ) à un nombre inférieur à N (généralement N-1). Le paramètre ddof nous permet de modifier le diviseur en fonction du montant spécifié.

Sauf indication contraire, NumPy calculera l'estimateur biaisé pour la variance (ddof=0, en divisant par N). C’est ce que vous voulez si vous travaillez avec l’ensemble de la distribution (et non un sous-ensemble de valeurs choisies au hasard dans une distribution plus large). Si le paramètre ddof est donné, NumPy est divisé par N - ddof au lieu.

Le comportement par défaut de std de MATLAB consiste à corriger le biais de la variance de l'échantillon en divisant par N-1. Cela supprime une partie (mais probablement pas la totalité) du biais de l'écart type. C'est probablement ce que vous voulez si vous utilisez la fonction sur un échantillon aléatoire d'une plus grande distribution.

La réponse de @hbaderts à Nice donne davantage de détails mathématiques.

138
Alex Riley

L'écart-type est la racine carrée de la variance. La variance d'une variable aléatoire X est définie comme

definition of variance

Un estimateur de la variance serait donc

biased estimator

où sample mean dénote la moyenne de l'échantillon. Pour sélectionné au hasard xi, on peut montrer que cet estimateur ne converge pas vers la variance réelle, mais vers

unbiased estimator

Si vous sélectionnez des échantillons de manière aléatoire et estimez la moyenne et la variance de l'échantillon, vous devrez utiliser un estimateur corrigé (non biaisé).

unbiased estimator

qui convergera vers sigma squared. Le terme de correction n-1 est aussi appelée correction de Bessel.

Maintenant par défaut, MATLABs std calcule l'estimateur sans biais avec le terme de correction n-1. Toutefois, NumPy (comme l'explique @ajcr) calcule l'estimateur biaisé sans terme de correction par défaut. Le paramètre ddof permet de définir n'importe quel terme de correction n-ddof. En le réglant sur 1, vous obtenez le même résultat que dans MATLAB.

De même, MATLAB permet d’ajouter un deuxième paramètre w, qui spécifie le "schéma de pesée". Le défaut, w=0, donne le terme de correction n-1 (estimateur non biaisé), tandis que pour w=1, seul n est utilisé comme terme de correction (estimateur biaisé).

60
hbaderts

Pour les personnes qui ne sont pas douées en statistiques, voici un guide simpliste:

  • Incluez ddof=1 Si vous calculez np.std() pour un échantillon extrait de votre jeu de données complet.

  • Assurez-vous que ddof=0 Si vous calculez np.std() pour la population complète.

Le DDOF est inclus pour les échantillons afin de contrebalancer les biais pouvant se produire dans les nombres.

3
MJM