Data Science : Test de Shapiro-Wilk

Comme indiqué dans le premier article Data science : Droite de Henry, nous continuons notre série sur les tests de normalité avec ce troisième article consacré au test de Shapiro-Wilk.

Considéré comme le plus fiable des tests de normalité, ce test publié en 1965 par Samuel Shapiro et Martin Wilk était à l’origine limité à des échantillons de moins de 50 individus. Mais en 1982 puis 1992, Royston a apporté des modifications au test de Shapiro-Wilk pour qu’il soit valable pour des échantillons contenant jusqu’à 5000 individus.

Pour les illustrations nous utiliserons scipy (scipy.stats.shapiro).

Un peu de théorie

La statistique de test est définie par :

    \[\frac{\sum_{i=1}^n (a_i x_i)^2}{\sum_{i=1}^n(x_i - \bar{x})^2}\]


x_i est la i-ème statistique d’ordre c’est-à-dire le i-ème plus petit nombre de l’échantillon

\bar{x} est la moyenne de l’échantillon

a_i = (a_1,...,a_n) = \frac{m^TV^{-1}}{(m^TV^{-1}V^{-1}m)^{1/2}} avec
m = (m_1,...,m_n)^T qui sont les valeurs attendus des statistiques d’ordre d’un échantillon indépendant et identiquement distribué suivant une loi normale, et V est la matrice de covariance de ces statistiques d’ordre.

La statistique de test W varie entre 0 et 1. De petites valeurs de W conduisent généralement au rejet de l’hypothèse de normalité de l’échantillon mais de grandes valeurs de W ne conduisent pas forcement à son acceptation.

Les hypothèses du test sont :

  • H0 : l’échantillon suit une loi normale.
  • H1 : l’échantillon ne suit pas une loi normale.

En pratique

Exemple 1

Considérons dans cet exemple un échantillon de taille n = 1000 provenant d’une loi normale :

from scipy import stats

n = 1000
mu = 2
sigma = 1.2
data = stats.norm.rvs(loc=mu, scale=sigma, size=n)

stats.shapiro(data)
ShapiroResult(statistic=0.9987794756889343, pvalue=0.741491436958313)

La p-value est très élevée (\leq 0.05) et la statistique de test est proche de 1. L’échantillon suit bien une loi normale (avec un risque 5 \%).

Exemple 2

Utilisons un échantillon qui provient d’une loi de Weibull :

n = 1000
c = 1.7
mu = 2.4
sigma = 0.6
data = scipy.weibull_min.rvs(c=c, loc = mu, scale=sigma, size=n)

scipy.shapiro(data)
ShapiroResult(statistic=0.9575144648551941, pvalue=1.9278042392567308e-16)

La p-value est très petite (inférieure au seuil de 0.05 fixé par défaut dans scipy). On rejette H0 avec un risque de 5 \%.

Il faut noter qu’en 1972, Samuel Sanford Shapiro et R. S. Francia ont mis en place une version plus simplifiée du test qu’ils ont nommé Shapiro-Francia. L’objectif étant de gagner en puissance et de le rendre valable pour des échantillons de taille plus grande.

Nous nous retrouvons très bientôt pour parler du test d’Anderson-Darling.