4 votes

Pourquoi ma fonction Kurtosis ne produit-elle pas le même résultat que scipy.stats.kurtosis ?

J'ai un problème de devoir dans lequel je suis supposé écrire une fonction pour le Kurtosis comme décrit ici :

Kurtosis, where theta is the standard deviation

Le thêta au dénominateur est l'écart type (racine carrée de la variance) et le x avec la barre au numérateur est la moyenne de x .

J'ai implémenté la fonction comme suit :

import numpy as np
from scipy.stats import kurtosis

testdata = np.array([1, 2, 3, 4, 5])

def mean(obs):
    return (1. / len(obs)) * np.sum(obs)

def variance(obs):
    return (1. / len(obs)) * np.sum((obs - mean(obs)) ** 2)

def kurt(obs):
    num = np.sqrt((1. / len(obs)) * np.sum((obs - mean(obs)) ** 4))
    denom = variance(obs) ** 2  # avoid losing precision with np.sqrt call
    return num / denom

Les deux premières fonctions, mean y variance ont fait l'objet d'une validation croisée avec numpy.mean y numpy.var respectivement.

J'ai essayé de faire une validation croisée kurt avec la déclaration suivante :

>>> kurtosis(testdata) == kurt(testdata)
False

Voici le résultat des deux fonctions de kurtosis :

>>> kurtosis(testdata)  # scipy.stats
-1.3

>>> kurt(testdata)  # my crappy attempt
0.65192024052026476

Où ai-je fait fausse route ? Est-ce que scipy.stats.kurtosis faire quelque chose de plus sophistiqué que ce qui est dans l'équation qu'on m'a donnée ?

10voto

NPE Points 169956

Par défaut, scipy.stats.kurtosis() :

  1. Calculer excès kurtosis (c'est-à-dire qu'il soustrait 3 du résultat).
  2. Corrige les biais statistiques (ce qui affecte certains des dénominateurs).

Ces deux comportements sont configurables par le biais d'arguments optionnels à l'adresse suivante scipy.stats.kurtosis() .

Enfin, le np.sqrt() dans votre méthode est inutile puisqu'il n'y a pas de racine carrée dans la formule. Une fois que je l'ai supprimé, la sortie de votre fonction correspond à ce que j'obtiens de la formule suivante kurtosis(testdata, False, False) .

J'ai essayé de faire une validation croisée de kurt avec la déclaration suivante

Vous ne devriez pas comparer des nombres à virgule flottante pour une égalité exacte. Même si les formules mathématiques sont les mêmes, de petites différences dans la façon dont elles sont traduites en code informatique peuvent affecter le résultat du calcul.

Enfin, si vous avez l'intention d'écrire du code numérique, je vous recommande vivement la lecture de Ce que tout informaticien devrait savoir sur l'arithmétique à virgule flottante .

P.S. C'est la fonction que j'ai utilisée :

In [51]: def kurt(obs):
   ....:     num = np.sum((obs - mean(obs)) ** 4)/ len(obs)
   ....:     denom = variance(obs) ** 2  # avoid losing precision with np.sqrt call
   ....:     return num / denom

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X