DETECCIÓN DE OUTLIERS CON R - MÉTODOS BÁSICOS
Introducción
Uno de los problemas que podemos encontrar durante el pre-procesamiento de datos en Machine Learning es la aparición de outliers.
Estos valores, que no son otra cosa que puntos muy alejados de los demás, pueden surgir debido a errores durante el experimento o bien ser valores legítimos que merecen un estudio más detallado. En todo caso, es importante determinar qué valores son outliers para su correcto tratamiento.
Los datos del problema
Algunos parámetros que necesitaremos definir
set.seed(12345)
media<-10
desv_tipica<-5
n_min<-100
n_max<-125
Vamos a generar nuestros datos de ejemplo. Más adelante, introduciremos algunos outliers a mano.
x<-rnorm(n_min,mean=media,sd=desv_tipica)
d <- density(x)
plot(d,main="curva de densidad de los datos",ylab="",xlab="")
En la curva de densidad, lo mismo que en el histograma, no se pueden
distinguir los outliers. No es un tipo de gráfico adecuado.
Detección de outliers con el z-score
Antes de nada, hay que aclarar que los métodos de detección de outliers se basan, casi todos, en que la distribución de partida tiene forma parecida a la normal. De otro modo, el estar alejado de la media carece de significado.
Con el criterio del z-score, diremos que son outliers aquellos valores de la distribución que tengan un z-score mayor, en valor absoluto, que 3.
Para hacernos una idea de cómo son realmente nuestros datos, vamos a estandarizarlos y sacaremos un resúmen de los mismos. En el summary podemos ver que el mínimo, -2.3553, es un valor relativamente extremo pero, con nuestro criterio, no lo suficiente para ser considerado outlier.
summary(scale(x))
## V1
## Min. :-2.3553
## 1st Qu.:-0.7493
## Median : 0.2140
## Mean : 0.0000
## 3rd Qu.: 0.5878
## Max. : 2.0022
Nótese que la probabilidad de obtener al menos igual de extremo que este es:
2*pnorm(-2.3553)
## [1] 0.01850776
Introduciendo outliers en los datos
Vamos a introducir unos cuantos outliers en los datos:
x[(n_min+1):n_max]<-rnorm(n_max-n_min,media,3*desv_tipica)
Ahora, tras forzar a que los datos se alejen aumentando la desviación típica, sí que tenemos outliers:
summary(scale(x))
## V1
## Min. :-2.58444
## 1st Qu.:-0.59812
## Median : 0.09173
## Mean : 0.00000
## 3rd Qu.: 0.38937
## Max. : 3.73797
Los outliers serán aquellos valores que tengan un z-score, en valor absoluto, por encima de tres:
outliers<- which(abs((x-media)/desv_tipica)>3)
print("lista de outliers")
## [1] "lista de outliers"
print(x[outliers])
## [1] -7.343350 -9.871329 33.341645 -8.452584 -9.860880 28.918634 29.788476
## [8] 42.700036 33.172954 29.821780 32.964327
Detección de outliers con Boxplot (cuartiles)
Uno de los métodos más usados, y más sencillos, para ver si una distribución tiene outliers es usando un boxplot. En nuestro caso:
boxplot(x,col="red",main="detección de outliers con boxplot",horizontal = TRUE)
Son outliers los valores que están fuera del intervalo (Q1-IQR, Q3+IQR), que son los círculos en el boxplot, donde Q1 y Q3 son los cuartiles e IQR=Q3-Q1 es el rango intercuartílico. Los valores de los cuartiles los podemos sacar de facilmente con summary:
summary(x)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -9.871 6.645 12.381 11.618 14.856 42.700
Este es un método gráfico sencillo para detectar outliers, y es por eso que suele ser el favorito. Notar que es muy complicado detectar outliers con el histograma, dado que nos agrupa los valores. En el histograma puede verse que hay valores cerca de 40 que posiblemente sean outliers, pero no se puede decir mucho más:
hist(x,main="los outliers no se ven de forma fácil en el histograma",xlab="",ylab="")
Z-Score Modificado
Si nos fijamos, en la propia fórmula del z-score interviene la media y la desviación típica. Estos dos valores pueden cambiar mucho si tenemos outliers. En nuestro ejemplo, la media no varía demasiado pero la desviación típica ha aumentado notablemente al introducir nuevos valores:
#Antes de meter outliers
cat("media=",mean(x[1:n_min]),"desv tipica=",sd(x[1:n_min]),"\n")
## media= 11.22599 desv tipica= 5.573654
#Después de meter outliers
cat("media=",mean(x[1:n_max]),"desv tipica=",sd(x[1:n_max]),"\n")
## media= 11.6185 desv tipica= 8.315079
De hecho, los outliers, en general, desplazan la media y aumentan la desviación típica. Es por esto por lo que se necesitan métodos robustos.
Para calcular el z-score modificado, necesitaremos previamente la desviación absoluta mediana, que se define como sigue:
MAD<-median(abs(x-median(x)))
MAD
## [1] 4.789478
Este es un valor robusto, dado que se calcula sobre la mediana(x) y no sobre la media. El z-score modificado es su estandarización, definida de la siguiente forma:
zscore_modif<-0.67*(x-median(x))/MAD
summary(zscore_modif)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -3.1129 -0.8024 0.0000 -0.1067 0.3462 4.2413
Al igual que teníamos que los z-scores por encima de tres, en valor absoluto, correspondían a outliers, en este caso los que son los valore mayores que 3.5 son los que consideraremos como tal.
outliers_modif<-which(abs(zscore_modif)>3.5)
cat("outliers según z-score modificado:",x[outliers_modif])
## outliers según z-score modificado: 42.70004
Observar que la lista de outliers que hemos obtenido es diferente de la que había resultado considerando simplemente el z-score, donde teníamos bastantes más. Pero, ¿entonces qué lista de outliers es la buena?
Esta pregunta no tiene una respuesta sencilla. Hay que mirar métodos diferentes y luego, con los distintos resultados, examinar uno a uno los outliers para decidir qué hacemos con esos datos. Los métodos de detección de outliers sólo indican ciertos valores que necesitan un estudio más detallado.
Resumen
Existen muchas formas de detectar outliers y muchas formas de definir el término “outlier”. En nuestros trabajos, deberemos usar varios métodos - a destacar el uso de boxplot para un primer vistazo - e investigar los valores que nos salgan reportados como outliers en cada uno de ellos.
No debemos olvidar que un outlier no es mas que un valor sospechoso, en ningún caso hay que quitarlo sin investigar previamente su presencia.
Comentarios
Publicar un comentario