Introducción

Los análisis de normalidad, también llamados contrastes de normalidad, tienen como objetivo analizar cuánto difiere la distribución de los datos observados respecto a lo esperado si procediesen de una distribución normal con la misma media y desviación típica. Pueden diferenciarse tres estrategias: las basadas en representaciones gráficas y en test de hipótesis.

Métodos gráficos

Histograma y curva normal

Consiste en representar los datos mediante un histograma y superponer la curva de una distribución normal con la misma media y desviación estándar que muestran los datos.

Datos de millas por galon para una serie de autos.

library(ggplot2)
ggplot(data = mtcars, aes(x = mpg)) +
  geom_histogram(aes(y = ..density.., fill = ..count..)) +
  scale_fill_gradient(low = "#DCDCDC", high = "#7C7C7C") +
  # scale_fill_gradient(low = 1, high = 2) +
  stat_function(fun = dnorm, colour = "firebrick",
                args = list(mean = mean(mtcars$mpg),
                            sd = sd(mtcars$mpg))) +
  ggtitle("Histograma + curva normal teórica") +
  theme_bw()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Gráfico de cuantiles teóricos (Gráficos Q-Q) (no solo normalida)

Consiste en comparar los cuantiles de la distribución observada con los cuantiles teóricos de una distribución normal con la misma media y desviación estándar que los datos. Cuanto más se aproximen los datos a una normal, más alineados están los puntos entorno a la recta. No solo para la normal, se puede emplear para

qqnorm(mtcars$mpg, pch = 19, col = "gray50")
qqline(mtcars$mpg)

qqplot(rbinom(n=100,size=100,p=.05), rbinom(n=100,size=100,p=.05) ) 

Distribución Normal

x = rnorm(1000) 
par(mfrow = c(1, 3)) 

hist(x, las=1, main="Distribución normal", font.main=1, ylab="Frecuencia") 
qqnorm(x, las=1, pch=18, main="Simetria", font.main=1, xlab="Cuantiles teóricos", ylab="Cuantiles muestrales") 
qqline(x) 
boxplot(x, las=1, main="Valores extremos", font.main=1, xlab="Datos de distribution normal", horizontal=T) 

Distribuciones Sesgadas

y = rchisq(1000, 1) 
z = -rchisq(1000, 1) 
par(mfrow = c(2, 3)) 
hist(y, las=1, main="Distribución Ji--2 (1 g.l.) " , font.main=1, ylab="Frecuencia")
qqnorm(y,las=1,pch=18, main="Sesgo a la derecha", font.main=1, xlab="Cuantiles teoricos", ylab="Cuantiles muestrales")
qqline(y) 
boxplot(y, las=1, main="Valores extremos", font.main=1, xlab="Ji-2 con 1 grado de libertad", horizontal=T) 

hist(z, las=1, main="Distribución -Ji-2(1 g.l.)", font.main=1, ylab="Frecuencia") 
qqnorm(z,las=1,pch=18, main="Sesgo a la izquierda",font.main=1, xlab="Cuantiles teóricos", ylab="Cuantiles muestral")
qqline(z) 
boxplot(z, las=1, main="Valores extremos" , font.main=1, xlab="-Ji-2 con 1 grado de libertad", horizontal= T) 

Distribuciones de colas cortas y largas

u = runif(500) 
v = rt(500, 2) 
par(mfrow = c(2, 3)) 
hist (u, las=1, main="Distribución uniforme", font.main=1, ylab="Frecuencia") 
qqnorm(u, las=1, pch=18, main="Colas cortas", font.main=1, xlab="Cuantiles teóricos", ylab="Cuantiles muestrales")
qqline(u)
boxplot (u, las=1, main="Valores extremos", font.main=1, xlab="Datos de distribution uniforme", horizontal=T) 
hist(v, las=1, main="Distribucion T (2 g.1.)", font.main=1, ylab= " Frecuencia" )
qqnorm(v,las=1,pch=18, main="Colas largas", font.main=1, xlab="Cuantiles teóricos", ylab="Cuantiles muestrales")
qqline(v) 
boxplot(v, las=1, main="Valores extremos", font.main=1, xlab="T con 2 grados de libertad", horizontal=T) 

Contraste de hipótesis

A continuación, se muestran los test de hipótesis más empleados para analizar la normalidad de los datos. En todos ellos, se considera como hipótesis nula que los datos sí proceden de una distribución normal y como hipótesis alternativa que no lo hacen. El p-value de estos test indica la probabilidad de obtener una distribución como la observada si los datos proceden realmente de una población con una distribución normal.

Cuando estos test se emplean con la finalidad de verificar las condiciones de métodos parámetricos, por ejemplo un t-test o un ANOVA, es importante tener en cuenta que, al tratarse de p-values, cuanto mayor sea el tamaño de la muestra más poder estadístico tienen y más fácil es encontrar evidencias en contra de la H0 (normalidad). Al mismo tiempo, cuanto mayor sea el tamaño de la muestra, menos sensibles son los métodos paramétricos a la falta de normalidad. Por esta razón, es importante no basar las conclusiones únicamente en el p-value del test, sino también considerar la representación gráfica y el tamaño de la muestra.

Test de Shapiro-Wilk

Este test se emplea para contrastar normalidad cuando el tamaño de la muestra es menor de 50. Para muestras grandes es equivalente al test de kolmogorov-Smirnov.

\[H_0:\ los\ datos\ se\ distribuyen\ son\ normalmente\] \[H_1:\ los\ datos\ no\ se\ distribuyen\ son\ normalmente\]

shapiro.test(x = mtcars$mpg)
## 
##  Shapiro-Wilk normality test
## 
## data:  mtcars$mpg
## W = 0.94756, p-value = 0.1229

Test de Kolmogorov-Smirnov (no solo para normalida) y modificación de Lillefors

El test de Kolmogorov-Smirnov permite estudiar si una muestra procede de una población con una determinada distribución (media y desviación típica), no está limitado únicamente a la distribución normal. Se ejecuta con la función ks.test().

$H_0: $La distribución de frecuencia observada es consistente con la distribución de la frecuencia teórica (Buen ajuste). \(H_1:\) La distribución de frecuencia observada no es coherente con la distribución de la frecuencia teórica (mal ajuste).

La estadística de Kolmogorov-Smirnov para una función de distribución acumulativa dada F (x) es

\[{\displaystyle D_{n}=\sup _{x}|F_{n}(x)-F(x)|}\]

donde sup x es el supremo del conjunto de distancias.

require(ggplot2)
## Loading required package: ggplot2
# simulate two distributions - your data goes here!
sample1 <- rnorm(10000, 10, 5)
sample2 <- rnorm(10000, 1, 5)
group <- c(rep("sample1", length(sample1)), rep("sample2", length(sample2)))
dat <- data.frame(KSD = c(sample1,sample2), group = group)
# create ECDF of data
cdf1 <- ecdf(sample1) 
cdf2 <- ecdf(sample2) 
# find min and max statistics to draw line between points of greatest distance
minMax <- seq(min(sample1, sample2), max(sample1, sample2), length.out=length(sample1)) 
x0 <- minMax[which( abs(cdf1(minMax) - cdf2(minMax)) == max(abs(cdf1(minMax) - cdf2(minMax))) )] 
y0 <- cdf1(x0) 
y1 <- cdf2(x0) 


# png(file = "c:/temp/ks.png", width = 1024, height = 768, type="cairo-png")
ggplot(dat, aes(x = KSD, group = group, color = group))+
  stat_ecdf(size=1) +
    theme_bw() +
    theme(legend.position ="top") +
    xlab("Sample") +
    ylab("empirical distribution function (ECDF)") +
    #geom_line(size=1) +
    geom_segment(aes(x = x0[1], y = y0[1], xend = x0[1], yend = y1[1]),
        linetype = "dashed", color = "red") +
    geom_point(aes(x = x0[1] , y= y0[1]), color="red", size=8) +
    geom_point(aes(x = x0[1] , y= y1[1]), color="red", size=8) +
    ggtitle("K-S Test: Sample 1 / Sample 2") +
    theme(legend.title=element_blank())

ks.test(x = mtcars$mpg,"pnorm", mean(mtcars$mpg), sd(mtcars$mpg))
## Warning in ks.test(x = mtcars$mpg, "pnorm", mean(mtcars$mpg), sd(mtcars
## $mpg)): ties should not be present for the Kolmogorov-Smirnov test
## 
##  One-sample Kolmogorov-Smirnov test
## 
## data:  mtcars$mpg
## D = 0.1263, p-value = 0.687
## alternative hypothesis: two-sided

A pesar de que continuamente se alude al test Kolmogorov-Smirnov como un test válido para contrastar la normalidad, esto no es del todo cierto. El Kolmogorov-Smirnov asume que se conoce la media y varianza poblacional, lo que en la mayoría de los casos no es posible. Esto hace que el test sea muy conservador y poco potente. Para solventar este problema, se desarrolló una modificación del Kolmogorov-Smirnov conocida como test Lilliefors. El test Lilliefors asume que la media y varianza son desconocidas, estando especialmente desarrollado para contrastar la normalidad. Es la alternativa al test de Shapiro-Wilk cuando el número de observaciones es mayor de 50. La función lillie.test() del paquete nortest permite aplicarlo.

# install.packages("nortest")
library("nortest")
lillie.test(x = mtcars$mpg)
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  mtcars$mpg
## D = 0.1263, p-value = 0.2171

Test de normalidad de Jarque-Bera

Las medidas de asimetría, sobre todo el coeficiente de asimetría de Fisher, junto con las medidas de apuntamiento o curtosis se utilizan para contrastar si se puede aceptar que una distribución estadística sigue la distribución normal. (ver, p.ej., el Test de Jarque-Bera) o para detección de atípicos.

El test estadístico \(JB\) se define como:

\[\displaystyle JB=\frac {n-k+1}{6}\left(\gamma _{1}^{2}+{\frac {1}{4}}(\beta_2-3)^{2}\right) \]

donde n es el número de observaciones (o grados de libertad en general); \(\gamma _{1}\) es la asimetría de la muestra, \(\beta_2\) la curtosis de la muestra y k el número de regresores

\(H_0\) es una hipótesis conjunta de que la asimetría es cero y curtosis es cero.

Las muestras de una distribución normal tienen una asimetría esperada de 0 y curtosis de 0. Como muestra la definición de JB, cualquier desviación de esto aumenta la estadística de JB.

El test de Jarque-Bera no requiere estimaciones de los parámetros que caracterizan la normal. El estadístico de Jarque-Bera cuantifica que tanto se desvían los coeficientes de asimetría y curtosis de los esperados en una distribución normal. Puede calcularse mediante la función jarque.bera.test() del paquete tseries.

# install.packages("tseries")
library("tseries")
jarque.bera.test(x = mtcars$mpg)
## 
##  Jarque Bera Test
## 
## data:  mtcars$mpg
## X-squared = 2.2412, df = 2, p-value = 0.3261

Consecuencias de la falta de normalidad

El hecho del no cumplimiento de la hipotesis la normalidad influye principalmente en las pruebas de hipótesis paramétricos (t-test, anova,…) y en los modelos de regresión.

Las principales consecuencias de que no se satisfaga el supuesto de normalidad son:

básicamente, la inferencia!

Bibliograflia

Joaquín Amat Rodrigo. Análisis de Normalidad: gráficos y contrastes de hipótesis j.amatrodrigo@gmail.com https://rpubs.com/Joaquin_AR/218465