web-dev-qa-db-fra.com

Comment utiliser correctement les fonctions skew et kurtosis de scipy?

L'asymétrie est un paramètre permettant de mesurer la symétrie d'un ensemble de données et le kurtosis pour mesurer le poids de ses queues par rapport à une distribution normale, voir par exemple ici .

scipy.stats fournit un moyen facile de calculer ces deux quantités, voir scipy.stats.kurtosis et scipy.stats.skew .

D'après ma compréhension, l'asymétrie et le kurtosis d'un distribution normale devraient tous deux être égaux à 0 en utilisant les fonctions susmentionnées. Ce n'est cependant pas le cas avec mon code:

import numpy as np
from scipy.stats import kurtosis
from scipy.stats import skew

x = np.linspace( -5, 5, 1000 )
y = 1./(np.sqrt(2.*np.pi)) * np.exp( -.5*(x)**2  )  # normal distribution

print( 'excess kurtosis of normal distribution (should be 0): {}'.format( kurtosis(y) ))
print( 'skewness of normal distribution (should be 0): {}'.format( skew(y) ))

La sortie est:

kurtose en excès de distribution normale (doit être 0): -0,307393087742

asymétrie de la distribution normale (doit être 0): 1.11082371392

Qu'est-ce que je fais mal ?

Les versions que j'utilise sont

python: 2.7.6
scipy : 0.17.1
numpy : 1.12.1
18
Alf

Ces fonctions calculent les moments de la distribution de la densité de probabilité (c'est pourquoi il ne prend qu'un paramètre) et ne se soucient pas de la "forme fonctionnelle" des valeurs.

Celles-ci sont destinées à des "ensembles de données aléatoires" (considérez-les comme des mesures telles que la moyenne, l'écart type, la variance):

import numpy as np
from scipy.stats import kurtosis, skew

x = np.random.normal(0, 2, 10000)   # create random values based on a normal distribution

print( 'excess kurtosis of normal distribution (should be 0): {}'.format( kurtosis(x) ))
print( 'skewness of normal distribution (should be 0): {}'.format( skew(x) ))

qui donne:

excess kurtosis of normal distribution (should be 0): -0.024291887786943356
skewness of normal distribution (should be 0): 0.009666157036010928

changer le nombre de valeurs aléatoires augmente la précision:

x = np.random.normal(0, 2, 10000000)

Menant à:

excess kurtosis of normal distribution (should be 0): -0.00010309478605163847
skewness of normal distribution (should be 0): -0.0006751744848755031

Dans votre cas, la fonction "suppose" que chaque valeur a la même "probabilité" (car les valeurs sont distribuées de manière égale et que chaque valeur n'apparaît qu'une seule fois), donc du point de vue de skew et kurtosis il s'agit d'une densité de probabilité non gaussienne (vous ne savez pas exactement de quoi il s'agit), ce qui explique pourquoi les valeurs obtenues ne sont même pas proches de 0:

import numpy as np
from scipy.stats import kurtosis, skew

x_random = np.random.normal(0, 2, 10000)

x = np.linspace( -5, 5, 10000 )
y = 1./(np.sqrt(2.*np.pi)) * np.exp( -.5*(x)**2  )  # normal distribution

import matplotlib.pyplot as plt

f, (ax1, ax2) = plt.subplots(1, 2)
ax1.hist(x_random, bins='auto')
ax1.set_title('probability density (random)')
ax2.hist(y, bins='auto')
ax2.set_title('(your dataset)')
plt.tight_layout()

enter image description here

25
MSeifert

Vous utilisez comme données la "forme" de la fonction de densité. Ces fonctions sont destinées à être utilisées avec des données échantillonnées à partir d'une distribution. Si vous échantillonnez à partir de la distribution, vous obtiendrez des statistiques d'échantillon qui s'approcheront de la valeur correcte à mesure que vous augmentez la taille de l'échantillon. Pour tracer les données, je recommanderais un histogramme.

%matplotlib inline
import numpy as np
import pandas as pd
from scipy.stats import kurtosis
from scipy.stats import skew

import matplotlib.pyplot as plt

plt.style.use('ggplot')

data = np.random.normal(0, 1, 10000000)
np.var(data)

plt.hist(data, bins=60)

print("mean : ", np.mean(data))
print("var  : ", np.var(data))
print("skew : ",skew(data))
print("kurt : ",kurtosis(data))

Sortie:

mean :  0.000410213500847
var  :  0.999827716979
skew :  0.00012294118186476907
kurt :  0.0033554829466604374

enter image description here

Sauf si vous utilisez une expression analytique, il est extrêmement improbable que vous obteniez un zéro lorsque vous utilisez des données.

5
Juan Leni