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 :
Test d’Anderson-Darling : Ce test est similaire au test de Shapiro-Wilk et est utilisé pour les échantillons de petite taille (n < 50).
Test de D’Agostino-Pearson : Ce test est utilisé pour les échantillons de grande taille (n > 50) et est basé sur le coefficient d’aplatissement et le coefficient d’asymétrie.
Test de Lilliefors : Ce test est une version modifiée du test de Kolmogorov-Smirnov et est utilisé pour les échantillons de petite taille (n < 50).
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