Data science : Test de Cramer-Von-Mises

Nous voilà arriver au dernier article de notre série, qui traitera du test de Cramer-Von-Mises.

Le test de Cramer-Von-Mises est une modification du test d’Anderson-Darling. C’est donc un test d’ajustement qui permet de tester si une variable continue donnée suit une loi de distribution fixée. La  normalité est un cas particulier.

A l’instar du test d’Anderson-Darling, le test de Cramer-Von-Mises peut être considéré comme une version puissante  du test de Kolmogorov-Smirnov car très peu sensible aux valeurs extrêmes.

Ce test est implémenté sous la bibliothèque scipy (stats.cramervonmises) et avec le logiciel openturns (NormalityTest.CramerVonMisesNormal).

Le processus d’installation d’ openturns se trouve dans le 1er article Data science : Droite de Henry.

Un peu de théorie

Ce test a été développé par Cramer(1928), Von-Mises(1931) et Smirnov(1936). La statistique de test est égal à :

    \[W_n^2 = n\int_{-\infty}^{\infty}\left\{F_n(x) - F(x)\right\}^2 [F(X)]{dF(x)} = \frac{1}{12n} + \sum_{i=1}^{n}\left[F_0(x_{(i)}) - \frac{2i - 1}{2n}\right]^2\]

.

F(x_i) est la fonction de distribution cumulative de la distribution spécifiée (normale dans notre cas)

– les x_i sont les données (ordonnées)

– et n la taille de l’échantillon.

Généralement on a tendance à rejeter l’hypothèse de normalité lorsque la statistique de test est très élevé, et réciproquement on a tendance à l’accepter lorsqu’elle plutôt petite.

En pratique

Exemple 1

Considérons pour ce premier exemple un échantillon provenant d’une loi normale.

import openturns as ot
ot.RandomGenerator.SetSeed(567)

n = 1000
mu = 2
sigma = 1.2

distribution = ot.Normal(mu, sigma)
sample = distribution.getSample(n)

test_result = ot.NormalityTest.CramerVonMisesNormal(sample)
print("p-value :", test_result.getPValue(), "\n",
     "threshold :", test_result.getThreshold(), "\n",
     "decison :", test_result.getBinaryQualityMeasure())
p-value : 0.6899604002686522 
threshold : 0.05 
decison : True

Comme attendu la p-value est supérieur au seuil 0.05. Ce qui est aussi directement donné par l’option getBinaryQualityMeasure d’openturns. On peut conclure à la normalité de notre échantillon avec une erreur de 5\%.

Exemple 2

Considérons ici un échantillon provenant d’une loi uniforme.

import numpy as np
from scipy import stats

n = 1000
a = 0
b = 2
data = np.random.uniform(a, b, n)

print(stats.cramervonmises(data, "norm"))
CramerVonMisesResult(statistic=121.27518940480644, pvalue=4.7820195692160894e-08)

La p-value est très petite et bien inférieur au seuil de 0.05 fixé par défaut dans scipy. La statistique de test est aussi très élevée. On rejette l’hypothèse de normalité avec un risque de 5\%.

Dans un prochain article bonus nous verrons ensemble, quels tests choisir et quelles stratégies adoptées lorsque nous disposons d’un échantillon dont nous voulons être certain de sa normalité ou non.