lunes, 28 de marzo de 2016

Transformar variables usando Box-Cox

Si se tiene un data set con variables que no tienen una distribución normal, y se quiere transformar esas variables para obtener mayor información de ellas, una forma es usar la transformación de box-cox, que busca un valor "lambda" para elevar la variable hasta encontrar la desviaciones estándar más cercana a cero, y así obtener una nueva variable con una distribución más "normal". Para detalles de box-cox ver referencia.

Conceptualmente las transformaciones quedan así:












 y el data set queda así:






El script debajo sigue estos pasos:

1. Identifica si una variable tiene distribución normal usando la asimetría y el coeficiente de variación. Si la simetría es menor a -1 o mayor a 1, y el coeficiente de variación es mayor a 1, entonces la variable no tiene una distribución normal y requiere una transformación.

2. Luego de identificar la variable que no tiene una distribución normal, calcula el valor lambda donde elevando la variable a ese valor se obtiene una distribución normal, y crea una nueva variable con el prefijo "BoxCox_"



# LIBRERIA Y DATOS
# -----------------------------------------------------------------------
library(MASS)
library(forecast);
df    <- Boston 
v     <- names(df[,sapply(Boston, is.numeric)])
 
 
# TRANSFORMACION BOX-COX
# ------------------------------------------------------------------------------
for (ii in 1:length(v)){
  asimetria       <- skewness(df[,v[ii]])[1]
  coef.variacion  <- sd(df[,v[ii]]) / mean(df[,v[ii]]) 
 
  if ( (asimetria < -1 | asimetria > 1) & coef.variacion > 1){
    print(paste("transformando variable: ",v[ii]))
    df$bc_tmp     <- BoxCox(df[,v[ii]],BoxCox.lambda(df[,v[ii]]))
    names(df)[names(df)=="bc_tmp"] <- paste("BoxCox_", v[ii], sep = "")
  }
}


Referencia:
http://www.isixsigma.com/tools-templates/normality/tips-recognizing-and-transforming-non-normal-data/

No hay comentarios:

Publicar un comentario