El presente trabajo indica el proceso para la imputación de datos el cual se realiza cuando la base de datos presenta datos faltantes.
Se lee la base de datos a utilizar, en la cual se encuentran las variables:
df<- read_excel("basenueva.xlsx")
skim(df)
| Name | df |
| Number of rows | 2037 |
| Number of columns | 7 |
| _______________________ | |
| Column type frequency: | |
| numeric | 7 |
| ________________________ | |
| Group variables | None |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| Mes | 193 | 0.91 | 7.37 | 3.80 | 1 | 5 | 9 | 10.00 | 12 | ▅▁▃▅▇ |
| NRO VISITAS | 0 | 1.00 | 1.51 | 0.73 | 0 | 1 | 1 | 2.00 | 3 | ▁▇▁▃▂ |
| Éxito | 0 | 1.00 | 0.68 | 0.47 | 0 | 0 | 1 | 1.00 | 1 | ▃▁▁▁▇ |
| CAPITAL | 0 | 1.00 | 0.78 | 0.41 | 0 | 1 | 1 | 1.00 | 1 | ▂▁▁▁▇ |
| Eficiencia | 0 | 1.00 | 0.01 | 0.04 | 0 | 0 | 0 | 0.01 | 1 | ▇▁▁▁▁ |
| Provincia | 0 | 1.00 | 12.60 | 5.74 | 1 | 9 | 12 | 17.00 | 24 | ▂▇▃▇▂ |
| Edad | 40 | 0.98 | 41.45 | 13.72 | 18 | 30 | 41 | 53.00 | 70 | ▇▆▇▇▃ |
Entre estas variables se observa que los atributos correspondientes al Mes y Edad tienen 193 y 40 datos faltantes respectivamente. Obteniendo asi un total de 233 datos faltantes en la base de datos Retail.
n_miss(df)
## [1] 233
n_miss(df$Mes)
## [1] 193
n_miss(df$Edad)
## [1] 40
Se observa el porcentaje de missing que tienen cada variable en relación al total de observaciones que se posee en la base,en este caso se tiene un total de 2037 datos.
La variable mes tiene 9.47% de datos faltantes.
La variable edad tiene 1.96% de datos faltantes.
apply(is.na(df),2,FUN="mean")*100
## Mes NRO VISITAS Éxito CAPITAL Eficiencia Provincia
## 9.474718 0.000000 0.000000 0.000000 0.000000 0.000000
## Edad
## 1.963672
Como se puede observar el porcentaje de datos perdido es menor al 20% por lo que se puede hacer la imputación.
Se procede a realizar un resumen de las variables que se tiene con sus datos y porcentajes correspondientes de datos faltantes, por lo que se concluye que Edad y Mes son variables a imputar.
miss_var_summary(df)
## # A tibble: 7 x 3
## variable n_miss pct_miss
## <chr> <int> <dbl>
## 1 Mes 193 9.47
## 2 Edad 40 1.96
## 3 NRO VISITAS 0 0
## 4 Éxito 0 0
## 5 CAPITAL 0 0
## 6 Eficiencia 0 0
## 7 Provincia 0 0
miss_var_table(df)
## # A tibble: 3 x 3
## n_miss_in_var n_vars pct_vars
## <int> <int> <dbl>
## 1 0 5 71.4
## 2 40 1 14.3
## 3 193 1 14.3
miss_case_summary(df)
## # A tibble: 2,037 x 3
## case n_miss pct_miss
## <int> <int> <dbl>
## 1 2000 2 28.6
## 2 2001 2 28.6
## 3 2017 2 28.6
## 4 2018 2 28.6
## 5 2029 2 28.6
## 6 2030 2 28.6
## 7 17 1 14.3
## 8 39 1 14.3
## 9 57 1 14.3
## 10 91 1 14.3
## # ... with 2,027 more rows
miss_case_table(df)
## # A tibble: 3 x 3
## n_miss_in_case n_cases pct_cases
## <int> <int> <dbl>
## 1 0 1810 88.9
## 2 1 221 10.8
## 3 2 6 0.295
df %>% group_by('Éxito') %>% miss_var_summary()
## # A tibble: 7 x 4
## # Groups: "Éxito" [1]
## `"Éxito"` variable n_miss pct_miss
## <chr> <chr> <int> <dbl>
## 1 Éxito Mes 193 9.47
## 2 Éxito Edad 40 1.96
## 3 Éxito NRO VISITAS 0 0
## 4 Éxito Éxito 0 0
## 5 Éxito CAPITAL 0 0
## 6 Éxito Eficiencia 0 0
## 7 Éxito Provincia 0 0
df %>% group_by('Éxito') %>% miss_case_summary()
## # A tibble: 2,037 x 4
## # Groups: "Éxito" [1]
## `"Éxito"` case n_miss pct_miss
## <chr> <int> <int> <dbl>
## 1 Éxito 2000 2 28.6
## 2 Éxito 2001 2 28.6
## 3 Éxito 2017 2 28.6
## 4 Éxito 2018 2 28.6
## 5 Éxito 2029 2 28.6
## 6 Éxito 2030 2 28.6
## 7 Éxito 17 1 14.3
## 8 Éxito 39 1 14.3
## 9 Éxito 57 1 14.3
## 10 Éxito 91 1 14.3
## # ... with 2,027 more rows
En el caso de la variable Mes, una imputación muy sencilla sería tomar la moda para completar estos datos faltantes, sin embargo esta aplicación puede generar errores.
# Moda
getmode <- function(v) {
uniqv <- unique(v)
uniqv[which.max(tabulate(match(v, uniqv)))]
}
Data_Impu_Moda<-ifelse(is.na(df$Mes),getmode(df$Mes),df$Mes)
El siguiente gráfico indica la imputación de la variable Mes, la figura en color rojo son los datos conocidos y la figura en color verde es la imputación, sin embargo se observa incosistencias en esta imputación puesto que no se ajusta la imputación con los datos de la base.
par(mfrow=c(1,1))
plot(density(df$Mes,na.rm = T),col=2,main="Mes") #ROJO CONOCIDO
lines(density(Data_Impu_Moda),col=3) # VERDE IMPUTACION
La librería mice permite realizar la imputacion de los datos mediante diferentes técnicas. En particular con la funcion mice, se generá: Multivariate Imputations by Chained Equations (MICE).
Imputar con algún estadístico de tendencia central (media, mediana, moda) consiste en cambiar todos los valores faltantes por el promedio de los datos que tenemos. Sin embargo el problema es que se esta disminuyendo artificialmente la variabilidad de la muestra.
# Media
imputed_data <- mice(df%>%select(Edad,Mes), method = "mean")
##
## iter imp variable
## 1 1 Edad Mes
## 1 2 Edad Mes
## 1 3 Edad Mes
## 1 4 Edad Mes
## 1 5 Edad Mes
## 2 1 Edad Mes
## 2 2 Edad Mes
## 2 3 Edad Mes
## 2 4 Edad Mes
## 2 5 Edad Mes
## 3 1 Edad Mes
## 3 2 Edad Mes
## 3 3 Edad Mes
## 3 4 Edad Mes
## 3 5 Edad Mes
## 4 1 Edad Mes
## 4 2 Edad Mes
## 4 3 Edad Mes
## 4 4 Edad Mes
## 4 5 Edad Mes
## 5 1 Edad Mes
## 5 2 Edad Mes
## 5 3 Edad Mes
## 5 4 Edad Mes
## 5 5 Edad Mes
Data_Impu_Media <- mice::complete(imputed_data)
sum(is.na(Data_Impu_Media))
## [1] 0
Como se observa en el gráfico los datos por media para la edad y mes han sido imputados. Por otro lado se visualiza que la imputación no se ajusta del todo con los datos de la base.
par(mfrow=c(1,2))
plot(density(df$Edad,na.rm = T),col=2,main="Edad")
lines(density(Data_Impu_Media$Edad),col=3)
plot(density(df$Mes,na.rm = T),col=2,main="Mes")
lines(density(Data_Impu_Media$Mes),col=3)
La imputación por regresión produce estimaciones que no son sesgadas de las medias bajo MCAR además esta imputación de regresión fortalece por simulación las relaciones en los datos.
# Regresión lineal usando bootstrap
imputed_data <- mice(df%>%select(Edad,Mes), method = "norm.boot")
##
## iter imp variable
## 1 1 Edad Mes
## 1 2 Edad Mes
## 1 3 Edad Mes
## 1 4 Edad Mes
## 1 5 Edad Mes
## 2 1 Edad Mes
## 2 2 Edad Mes
## 2 3 Edad Mes
## 2 4 Edad Mes
## 2 5 Edad Mes
## 3 1 Edad Mes
## 3 2 Edad Mes
## 3 3 Edad Mes
## 3 4 Edad Mes
## 3 5 Edad Mes
## 4 1 Edad Mes
## 4 2 Edad Mes
## 4 3 Edad Mes
## 4 4 Edad Mes
## 4 5 Edad Mes
## 5 1 Edad Mes
## 5 2 Edad Mes
## 5 3 Edad Mes
## 5 4 Edad Mes
## 5 5 Edad Mes
Data_Impu_boot <- mice::complete(imputed_data)
sum(is.na(Data_Impu_boot))
## [1] 0
par(mfrow=c(1,2))
plot(density(df$Edad,na.rm = T),col=2,main="Edad")
lines(density(Data_Impu_boot$Edad),col=3)
plot(density(df$Mes,na.rm = T),col=2,main="Mes")
lines(density(Data_Impu_boot$Mes),col=3)
IMPORTANTE
Es importante señalar que para los dos anteriores metodos se asumió a la variable Mes como una variable cuantitativa, cuando realmente debe ser tratada como cualitativa es decir una factor de 12 categorias.
El objetivo de estos métodos es obtener individuos más homogéneos con respecto a la variable que se desea discriminar dentro de cada subgrupo y heterogéneos entre los subgrupos. Para la construcción del árbol se requiere información de variables explicativas.
df$Mes<-as.factor(df$Mes)
imputed_data <- mice(df%>%select(Edad,Mes), method = "cart")
##
## iter imp variable
## 1 1 Edad Mes
## 1 2 Edad Mes
## 1 3 Edad Mes
## 1 4 Edad Mes
## 1 5 Edad Mes
## 2 1 Edad Mes
## 2 2 Edad Mes
## 2 3 Edad Mes
## 2 4 Edad Mes
## 2 5 Edad Mes
## 3 1 Edad Mes
## 3 2 Edad Mes
## 3 3 Edad Mes
## 3 4 Edad Mes
## 3 5 Edad Mes
## 4 1 Edad Mes
## 4 2 Edad Mes
## 4 3 Edad Mes
## 4 4 Edad Mes
## 4 5 Edad Mes
## 5 1 Edad Mes
## 5 2 Edad Mes
## 5 3 Edad Mes
## 5 4 Edad Mes
## 5 5 Edad Mes
Data_Impu_tree <- mice::complete(imputed_data)
sum(is.na(Data_Impu_tree))
## [1] 0
par(mfrow=c(1,2))
plot(density(df$Edad,na.rm = T),col=2,main="Edad")
lines(density(Data_Impu_tree$Edad),col=3)
#Para graficar les hacemos numericas de lo contrario usaríamos histograma
plot(density(as.numeric(df$Mes),na.rm = T),col=2,main="Mes")
lines(density(as.numeric(Data_Impu_tree$Mes)),col=3)
El bosque aleatorio es un algoritmo de clasificación que consta de una serie de árboles de decisiones.Su predicción es más precisa que la de un árbol en particular. Se procede a realizar este método para las dos variables.
# Random forest
df$Mes<-as.factor(df$Mes)
imputed_data <- mice(df%>%select(Edad,Mes), method = "rf")
##
## iter imp variable
## 1 1 Edad Mes
## 1 2 Edad Mes
## 1 3 Edad Mes
## 1 4 Edad Mes
## 1 5 Edad Mes
## 2 1 Edad Mes
## 2 2 Edad Mes
## 2 3 Edad Mes
## 2 4 Edad Mes
## 2 5 Edad Mes
## 3 1 Edad Mes
## 3 2 Edad Mes
## 3 3 Edad Mes
## 3 4 Edad Mes
## 3 5 Edad Mes
## 4 1 Edad Mes
## 4 2 Edad Mes
## 4 3 Edad Mes
## 4 4 Edad Mes
## 4 5 Edad Mes
## 5 1 Edad Mes
## 5 2 Edad Mes
## 5 3 Edad Mes
## 5 4 Edad Mes
## 5 5 Edad Mes
Data_Impu_tree <- mice::complete(imputed_data)
sum(is.na(Data_Impu_tree))
## [1] 0
Con los datos imputados podemos ver gráficamente cuánto se ajusta la imputación realizada con la base original en este caso se ajustan correctamente.
par(mfrow=c(1,2))
plot(density(df$Edad,na.rm = T),col=2,main="Edad")
lines(density(Data_Impu_tree$Edad),col=3)
#Para graficar les hacemos numericas de lo contrario usaríamos histograma
plot(density(as.numeric(df$Mes),na.rm = T),col=2,main="Mes")
lines(density(as.numeric(Data_Impu_tree$Mes)),col=3)
Se determina que se puede combinar los métodos, en este caso se especifíca como vector los métodos a utilizarse para cada variable.
Se utilizará el método de regresión bayesiana para la variable numerica Edad y se aplicará el método de random forest para la variable categórica Mes puesto que es la mas precisa.
# Combinado
df$Mes<-as.factor(df$Mes)
imputed_data <- mice(df%>%select(Edad,Mes), method = c("norm",'cart'))
##
## iter imp variable
## 1 1 Edad Mes
## 1 2 Edad Mes
## 1 3 Edad Mes
## 1 4 Edad Mes
## 1 5 Edad Mes
## 2 1 Edad Mes
## 2 2 Edad Mes
## 2 3 Edad Mes
## 2 4 Edad Mes
## 2 5 Edad Mes
## 3 1 Edad Mes
## 3 2 Edad Mes
## 3 3 Edad Mes
## 3 4 Edad Mes
## 3 5 Edad Mes
## 4 1 Edad Mes
## 4 2 Edad Mes
## 4 3 Edad Mes
## 4 4 Edad Mes
## 4 5 Edad Mes
## 5 1 Edad Mes
## 5 2 Edad Mes
## 5 3 Edad Mes
## 5 4 Edad Mes
## 5 5 Edad Mes
Data_Impu_Mix <- mice::complete(imputed_data)
sum(is.na(Data_Impu_Mix))
## [1] 0
Con los datos imputados podemos ver gráficamente cuánto se ajusta nuestra imputación con la base origina en este caso se ajustan bien.
par(mfrow=c(1,2))
plot(density(df$Edad,na.rm = T),col=2,main="Edad")
lines(density(Data_Impu_Mix$Edad),col=3)
plot(density(as.numeric(df$Mes),na.rm = T),col=2,main="Mes")
lines(density(as.numeric(Data_Impu_Mix$Mes)),col=3)
Finalmente se reemplaza las variables imputadas en la base original.
df<-df%>%mutate(Mes = Data_Impu_Mix$Mes, Edad = Data_Impu_Mix$Edad)
skim(df)
| Name | df |
| Number of rows | 2037 |
| Number of columns | 7 |
| _______________________ | |
| Column type frequency: | |
| factor | 1 |
| numeric | 6 |
| ________________________ | |
| Group variables | None |
Variable type: factor
| skim_variable | n_missing | complete_rate | ordered | n_unique | top_counts |
|---|---|---|---|---|---|
| Mes | 0 | 1 | FALSE | 9 | 10: 386, 1: 320, 9: 290, 11: 244 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| NRO VISITAS | 0 | 1 | 1.51 | 0.73 | 0 | 1 | 1 | 2.00 | 3.00 | ▁▇▁▃▂ |
| Éxito | 0 | 1 | 0.68 | 0.47 | 0 | 0 | 1 | 1.00 | 1.00 | ▃▁▁▁▇ |
| CAPITAL | 0 | 1 | 0.78 | 0.41 | 0 | 1 | 1 | 1.00 | 1.00 | ▂▁▁▁▇ |
| Eficiencia | 0 | 1 | 0.01 | 0.04 | 0 | 0 | 0 | 0.01 | 1.00 | ▇▁▁▁▁ |
| Provincia | 0 | 1 | 12.60 | 5.74 | 1 | 9 | 12 | 17.00 | 24.00 | ▂▇▃▇▂ |
| Edad | 0 | 1 | 41.53 | 13.74 | 18 | 30 | 42 | 53.00 | 81.68 | ▇▇▇▅▁ |
#write.xlsx(df, file = "Base_Retail_Imputacion.xlsx", sheetName = "DATOS", append = TRUE)