Tests de répartition sous R

L'essentiel de cette page

Avant de nombreux tests statistiques, il est important de contrôler la normalité ou la réparition des données. Voici quelques tests.

Les tests recommandés sont Shapiro (petit échantillon) et Jarque-Bera (grand échantillon).

Au-delà de 1000 valeurs, inutile de contrôler la normalité, la plupart du temps les tests deviennent hypersensible à la moindre variation en faisant des erreurs de type 1.

Evitons le test de Kolmogorov-Smirnov pour contrôler la normalité car il compare la répartition à un échantillon de même moyenne et même variance ce qui le rend trop conservateur. Il peut en revanche permettre de continuer sur les très grands échantillons.

Les graphiques classiques pour étudier les répartitions sont :

Les tests classiques pour étudier les répartitions sont :

Test de Shapiro

Contrôler si un échantillon petit (<~50) suit la loi normale

shapiro.test()

Test de Jarque-Bera

Contrôler si un échantillon moyen (>~50 & <~1000) suit la loi normale 

jarque.bera.test() {tseries}

Contrôler si un échantillon grand (>~1000) suit une loi (normale ou autre) OU comparer la répartition de deux variables

ks.test()

Une comparaison entre les tests de Shapiro-Wilk, Jarque-Bera et Kolmogorov-Smirnov montre clairement une grande sensibilité du test de Shapiro-Wilk qui aura tendance à bien détecter les échantillons anormaux (sur les petits échantillons en particulier, là où les autres ne détecteront rien) quitte à déclarer anormal ce qui ne l'est pas. Les tests de Shapiro-Wilk et Jarque-Bera devenant trop sensible pour les échantillons de grandes tailles, on devrait favoriser Shapiro-Wilk pour les petits échantillons, Jarque-Bera lorsque la taille augmente et, passé une certaine taille, Kolmogorov-Smirnov semble une alternative pour éviter la sensibilité des tests à la moindre variation.

Cliquer ici pour récupérer le bout de code qui permet de vérifier quel tests marche le mieux selon la distribution des données attendue

library(tseries)

sw <- c()

jb <- c()

ks <- c()

sample <- 3:1000

objectif <- FALSE

y <- rnorm(200,20,20)

for (n in sample ) {

print(n)

sw_temp <- c()

jb_temp <- c()

ks_temp <- c()

for (iter in 1:500) {

x <- c(rnorm(n,-1,1),rnorm(n,1,1))

#x <- sample(y,4*n,replace=T)

#x <- rpois(n*2,lambda=5)

#x <- rnorm(n*2,10,40)

sw_temp <- c(sw_temp,shapiro.test(x)$p.value)

jb_temp <- c(jb_temp,jarque.bera.test(x)$p.value)

ks_temp <- c(ks_temp,ks.test(x,"pnorm",mean=mean(x),sd=sd(x))$p.value)

}

sw_temp <- ifelse(sw_temp<=0.05,FALSE,TRUE) ; sw_temp <- length(which(sw_temp==objectif ))/500

jb_temp <- ifelse(jb_temp<=0.05,FALSE,TRUE) ; jb_temp <- length(which(jb_temp ==objectif ))/500

ks_temp <- ifelse(ks_temp<=0.05,FALSE,TRUE) ; ks_temp <- length(which(ks_temp ==objectif ))/500

sw <- c(sw,sw_temp)

jb  <- c(jb,jb_temp)

ks <- c(ks,ks_temp)

}


plot(sample*4,sw,type="l",lwd=2,col="white",xlab="Taille de l'échantillon",

main="Capacité à détecter la non-normalité d'un échantillon\nà deux composantes normales",

ylab="Pourcentage de succès",ylim=c(0,1),log="x")

lines(smooth.spline(sample *4,sw),col="orange",lwd=2) 

#points(2:1000*4,jb,type="l",lwd=2,col="blue")

lines(smooth.spline(sample *4,jb),col="blue",lwd=2) 

#points(2:1000*4,ks,type="l",lwd=2,col="red")

lines(smooth.spline(sample *4,ks),col="red",lwd=2) 

legend(x="topleft", legend=c("Shapirow,Wilk","Jarque-Bera","Kolmogorov-Smirnov"), col=c("orange","blue","red"),pch=16)

Pour aller loin, il existe d'autres tests que je n'ai pas encore eu le temps de creuser :

Pour généralisation l'approche, j'ai demandé à Consensus (moteur de recherche scientifique) connecté à GPT de réaliser ce tableau comparatif qu'il me faudrait prendre le temps de vérifier et de généraliser sous la forme de tuto. Une base éventuelle pour gagner du temps à ceux qui cherchent une comparaison rapide.

Distribution

Caractéristiques

Applications 

Particularités 

Test de mise en évidence 

sous R

Normale

Symétrique, cloche

Nature, erreurs


Moyenne, écart-type 

Shapiro-Wilk, Kolmogorov-Smirnov 

shapiro.test(data)

ks.test(data, "pnorm", mean = mean(data), sd = sd(data)) 

Poisson

Événements rares

Comptage sur un temps défini


Moyenne = Variance

Rapport de vraisemblance (variance // moyenne)

Comparaison des variances et moyennes

Quasi-Poisson

Surdispersion

Comptage surdispersé


Utile pour surdispersion

Test de surdispersion

summary(glm(data ~ ..., family = quasipoisson))

Gamma

Continue, positive

Temps d'attente, contrairement à poisson, mesure en continue


Forme, échelle

Kolmogorov-Smirnov

ks.test(data, "pgamma", shape = estimate, rate = estimate)

Tweedie

Masse à zéro, continue

Régression flexible


Puissance, dispersion

Estimation des paramètres

Utilisation du package tweedie

Binomiale

Succès dans essais

Expériences binaires


Indépendance des essais

Test de binomialité

Comparaison avec distribution théorique cf. binom.test() qbinom, dbinom()...

Uniforme

Événements égaux

Résultats équivalents


Événements équivalents

Kolmogorov-Smirnov

ks.test(data, "punif", min = minimum, max = maximum)

Exponentielle

Temps entre événements

Temps d'attente


Mémoire courte

Kolmogorov-Smirnov

ks.test(data, "pexp", rate = estimate)

Log-Normale

Croissance exponentielle

Revenus, population


Log-transformation normale

Shapiro-Wilk sur log

shapiro.test(log(data))

Bernoulli

Binaire

Expériences à deux issues


Succès/Échec

Test du χ²

Comparaison des fréquences observées/attendues

Géométrique

Premier succès

Séries d'essais


Base de binomiale négative

Test de dispersion

Comparaison de la variance et la moyenne