La literatura realiza una distinción entre el patrón de los datos faltantes y el mecanismo que los produce. El patrón describe cuales son los valores observados en la matriz de datos y cuáles no, mientras que el mecanismo expresa la relación entre la ausencia de datos y las variables en la matriz.
Sea \(Y_i=(y_{ij})\ \) una matriz de datos rectangular \(n\times k\) sin valores faltantes, donde \(y_{ij}\) es el valor de la variable \(Y_{j}\) para el sujeto \(i\). Se define la matriz indicadora de datos faltantes como \(M=(m_{ij})\) tal que \(m_{ij}=1\) si \(y_{ij}\) es no observado y \(m_{ij}=0\) caso contrario. Decimos entonces que \(M\) describe el patrón de los datos faltantes en \(Y\).
Los mecanismos, por otra parte, son caracterizados por la distribución condicional de \(M\) dado \(Y\). Es decir, \(f(M|Y, \phi)\) donde \(\phi\) recoge los parametros exógenos que afectan la distribución de los datos. Si los datos faltantes no dependen de \(Y\), es decir, \[ f(M|Y, \phi) = f(M, \phi) \] para todo \(Y\), \(\phi\), entonces se dice que los datos faltantes son puramente aleatorios o MCAR (Missing Completely at Random).
Ahora, denotando por \(Y_{obs}\) a los componentes observados de \(Y\), y a \(Y_{mis}\) a los datos faltantes, un supuesto menos restrictivo que el MCAR es que el patrón depende de \(Y_{obs}\) y no de \(Y_{mis}\). Esto es, que el patrón no depende de los datos faltantes.
\[ f(M|Y, \phi) = f(M|Y_{obs},\phi) \] para todo \(Y_{mis}\), \(\phi\). Aqui se dice que los datos faltantes son aleatorios o MAR (Missing at Random).
La necesidad de hacer esta distinción radica en que los métodos de regresión que se utilizan en este trabajo requieren, como se verá más adelante, que los datos faltantes sean MAR.
Se usa el paquete MICE para realizar la imputación multiple sobre la base de variables con Na´s, y se estima mediante dos formas: Árboles de clasificación y regresión (CART) y Regresión lineal usando bootstrap. Los métodos se describen más adelante.
La base con la que se está trabajando cuenta con las siguientes variables:
source("librerias.r")
attach(base)
glimpse(base)
## Rows: 79,146
## Columns: 71
## $ Id <int> 2, 5, 6, 7, 8, 10, 11, 14, 15, 16, 17, 18, 19, ...
## $ Product_Info_1 <chr> "nivel1", "nivel1", "nivel1", "nivel1", "nivel1...
## $ Product_Info_2 <chr> "D3", "A1", "E1", "D4", "D2", "D2", "A8", "D2",...
## $ Product_Info_3 <int> 10, 26, 26, 10, 26, 26, 10, 26, 26, 21, 26, 26,...
## $ Product_Info_4 <dbl> 0.07692308, 0.07692308, 0.07692308, 0.48717949,...
## $ Product_Info_5 <chr> "nivel2", "nivel2", "nivel2", "nivel2", "nivel2...
## $ Product_Info_6 <chr> "nivel1", "nivel3", "nivel3", "nivel3", "nivel3...
## $ Product_Info_7 <chr> "nivel1", "nivel1", "nivel1", "nivel1", "nivel1...
## $ Ins_Age <dbl> 0.64179104, 0.05970149, 0.02985075, 0.16417910,...
## $ Ht <dbl> 0.5818182, 0.6000000, 0.7454545, 0.6727273, 0.6...
## $ Wt <dbl> 0.1485356, 0.1317992, 0.2887029, 0.2050209, 0.2...
## $ BMI <dbl> 0.3230080, 0.2722877, 0.4287804, 0.3524377, 0.4...
## $ Employment_Info_1 <dbl> 0.0280, NA, 0.0300, 0.0420, 0.0270, 0.3250, 0.1...
## $ Employment_Info_2 <int> 12, 1, 9, 9, 9, 15, 1, 12, 9, 1, 9, 3, 9, 9, 3,...
## $ Employment_Info_3 <chr> "nivel1", "nivel3", "nivel1", "nivel1", "nivel1...
## $ Employment_Info_5 <chr> "nivel3", "nivel2", "nivel2", "nivel3", "nivel2...
## $ Employment_Info_6 <dbl> NA, 0.0018, 0.0300, 0.2000, 0.0500, 1.0000, 0.8...
## $ InsuredInfo_1 <chr> "nivel1", "nivel1", "nivel1", "nivel2", "nivel1...
## $ InsuredInfo_2 <chr> "nivel2", "nivel2", "nivel2", "nivel2", "nivel2...
## $ InsuredInfo_3 <int> 6, 6, 8, 8, 6, 8, 3, 6, 3, 3, 4, 3, 8, 3, 3, 3,...
## $ InsuredInfo_4 <chr> "nivel3", "nivel3", "nivel3", "nivel3", "nivel3...
## $ InsuredInfo_5 <chr> "nivel1", "nivel1", "nivel1", "nivel1", "nivel1...
## $ InsuredInfo_6 <chr> "nivel2", "nivel2", "nivel1", "nivel2", "nivel2...
## $ InsuredInfo_7 <chr> "nivel1", "nivel1", "nivel1", "nivel1", "nivel1...
## $ Insurance_History_1 <chr> "nivel1", "nivel2", "nivel2", "nivel2", "nivel2...
## $ Insurance_History_2 <chr> "nivel1", "nivel1", "nivel1", "nivel1", "nivel1...
## $ Insurance_History_3 <chr> "nivel3", "nivel3", "nivel1", "nivel1", "nivel1...
## $ Insurance_History_4 <chr> "nivel1", "nivel1", "nivel3", "nivel3", "nivel3...
## $ Insurance_History_7 <chr> "nivel1", "nivel1", "nivel3", "nivel3", "nivel3...
## $ Insurance_History_8 <chr> "nivel1", "nivel3", "nivel2", "nivel2", "nivel2...
## $ Insurance_History_9 <chr> "nivel2", "nivel2", "nivel3", "nivel3", "nivel3...
## $ Family_Hist_1 <chr> "nivel2", "nivel2", "nivel3", "nivel3", "nivel2...
## $ Medical_History_1 <int> 4, 5, 10, NA, NA, 6, 5, 6, 4, NA, 1, 4, 5, NA, ...
## $ Medical_History_2 <int> 112, 412, 3, 350, 162, 491, 600, 145, 16, 162, ...
## $ Medical_History_3 <chr> "nivel2", "nivel2", "nivel2", "nivel2", "nivel2...
## $ Medical_History_4 <chr> "nivel1", "nivel1", "nivel2", "nivel2", "nivel2...
## $ Medical_History_5 <chr> "nivel1", "nivel1", "nivel1", "nivel1", "nivel1...
## $ Medical_History_6 <chr> "nivel3", "nivel3", "nivel3", "nivel3", "nivel3...
## $ Medical_History_7 <chr> "nivel2", "nivel2", "nivel2", "nivel2", "nivel2...
## $ Medical_History_8 <chr> "nivel2", "nivel2", "nivel2", "nivel2", "nivel2...
## $ Medical_History_9 <chr> "nivel1", "nivel1", "nivel2", "nivel2", "nivel2...
## $ Medical_History_11 <chr> "nivel3", "nivel3", "nivel3", "nivel3", "nivel3...
## $ Medical_History_12 <chr> "nivel2", "nivel2", "nivel2", "nivel2", "nivel2...
## $ Medical_History_13 <chr> "nivel3", "nivel3", "nivel3", "nivel3", "nivel3...
## $ Medical_History_14 <chr> "nivel3", "nivel3", "nivel3", "nivel3", "nivel3...
## $ Medical_History_16 <chr> "nivel3", "nivel1", "nivel1", "nivel1", "nivel1...
## $ Medical_History_17 <chr> "nivel3", "nivel3", "nivel3", "nivel3", "nivel3...
## $ Medical_History_18 <chr> "nivel1", "nivel1", "nivel1", "nivel1", "nivel1...
## $ Medical_History_19 <chr> "nivel1", "nivel1", "nivel1", "nivel1", "nivel1...
## $ Medical_History_20 <chr> "nivel2", "nivel2", "nivel2", "nivel2", "nivel2...
## $ Medical_History_21 <chr> "nivel1", "nivel1", "nivel1", "nivel2", "nivel1...
## $ Medical_History_22 <chr> "nivel2", "nivel2", "nivel2", "nivel2", "nivel2...
## $ Medical_History_23 <chr> "nivel3", "nivel3", "nivel3", "nivel3", "nivel3...
## $ Medical_History_25 <chr> "nivel1", "nivel1", "nivel2", "nivel1", "nivel2...
## $ Medical_History_26 <chr> "nivel3", "nivel3", "nivel2", "nivel3", "nivel2...
## $ Medical_History_27 <chr> "nivel3", "nivel3", "nivel3", "nivel3", "nivel3...
## $ Medical_History_28 <chr> "nivel1", "nivel1", "nivel1", "nivel1", "nivel1...
## $ Medical_History_29 <chr> "nivel3", "nivel3", "nivel3", "nivel3", "nivel3...
## $ Medical_History_30 <chr> "nivel2", "nivel2", "nivel2", "nivel2", "nivel2...
## $ Medical_History_31 <chr> "nivel3", "nivel3", "nivel3", "nivel3", "nivel3...
## $ Medical_History_33 <chr> "nivel1", "nivel3", "nivel3", "nivel3", "nivel3...
## $ Medical_History_34 <chr> "nivel3", "nivel1", "nivel3", "nivel3", "nivel3...
## $ Medical_History_35 <chr> "nivel1", "nivel1", "nivel1", "nivel1", "nivel1...
## $ Medical_History_36 <chr> "nivel2", "nivel2", "nivel3", "nivel2", "nivel3...
## $ Medical_History_37 <chr> "nivel2", "nivel2", "nivel2", "nivel2", "nivel2...
## $ Medical_History_38 <chr> "nivel1", "nivel1", "nivel1", "nivel1", "nivel1...
## $ Medical_History_39 <chr> "nivel3", "nivel3", "nivel3", "nivel3", "nivel3...
## $ Medical_History_40 <chr> "nivel3", "nivel3", "nivel3", "nivel3", "nivel3...
## $ Medical_History_41 <chr> "nivel3", "nivel1", "nivel1", "nivel1", "nivel1...
## $ Medical_Keyword_3 <chr> "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si",...
## $ Response <int> 8, 4, 8, 8, 8, 8, 8, 1, 8, 1, 6, 2, 7, 3, 8, 5,...
En el análisis exploratorio, se observó que las variables : Employment_Info 1, Employment_Info 6 y Medical History 1 (todas variables continuas) deben ser imputadas, ya que representan el 0.007724 % de datos faltantes en la base.
base_na<-base[,c(13,17,33)]
En la siguinete tabla se observa el número de datos faltantes, no faltantes y proporciones en cada variable de interés:
V<-data.frame(Variables=c("Employment_Info_1","Employment_Info_6","Medical_History_1"),
Nas=c(n_miss(base$Employment_Info_1),n_miss(base$Employment_Info_6),
n_miss(base$Medical_History_1)),
Sin_Nas=c(n_complete(base$Employment_Info_1),n_complete(base$Employment_Info_6),
n_complete(base$Medical_History_1)))
V$Prop<-c(25.5,23.0 ,6.33)
datatable(V,options = list(initComplete = JS(
"function(settings, json) {",
"$(this.api().table().header()).css({'background-color': '#fca56f', 'color': '#fff'});",
"}")))
Ahora se observa el patrón de los datos faltantes:
vis <- vis_miss(base_na)
grid.arrange(vis)
aggr(base_na,numbers=T,sortVar=T)
##
## Variables sorted by number of missings:
## Variable Count
## Employment_Info_6 0.25516135
## Medical_History_1 0.22991686
## Employment_Info_1 0.06332601
Se puede observar que los datos tienen un patrón general. A partir de este patrón y de la naturaleza de los datos es probable que estos sean MAR.
Para la imputación multiple se hará uso de 2 métodos: - Árboles de clasificación y regresión - Regresión lineal usando bootstrap
Los árboles de clasificación y regresión (CART, Classification and Regression Trees) son una clase popular de algoritmos de Machine Learning que trabajan buscando predictores y puntos de corte para dividir la muestra. Los puntos de corte dividen la muestra en submuestras más homogéneas. El proceso de división se repite en las submuestras, de modo que una serie de divisiones define un árbol binario. La variable objetivo puede ser discreta (árbol de clasificación) o continua (árbol de regresión).
Los métodos CART tienen propiedades que los hacen atractivos para la imputación: son robustos frente a los valores atípicos, pueden tratar con multicolinealidad y distribuciones sesgadas, y son lo suficientemente flexibles como para adaptarse a interacciones y relaciones no lineales. Además, muchos aspectos del ajuste del modelo se han automatizado.
Al implementar este método obtenemos los datos imputados y el siguiente summary:
imp1 <- mice(base_na[,names(base_na) %in% columns], seed=123,
m=5,method = "cart",print = F)
complete_data<- mice::complete(imp1)
summary(imp1)
## Class: mids
## Number of multiple imputations: 5
## Imputation methods:
## Employment_Info_1 Employment_Info_6 Medical_History_1
## "cart" "cart" "cart"
## PredictorMatrix:
## Employment_Info_1 Employment_Info_6 Medical_History_1
## Employment_Info_1 0 1 1
## Employment_Info_6 1 0 1
## Medical_History_1 1 1 0
La regresión lineal es un método bayesiano que utiliza la función de máxima verosimilitud para calcular iterativamente los parámetros.La inferencia es válida solo si el mecanismo de datos faltantes es ignorable. Esto se satisface asumiendo MAR, a pesar de que hacer tests estadísticos para esto, es en realidad, imposible puesto que se requeriría información no disponible acerca de los datos faltantes (Li, 2018). Cabe mencionar que el método necesariamente asume que los datos son generados por un modelo descrito por una función de probabilidad \(f(Y|\theta)\) donde \(\theta\) es el vector de parámetros de la función. \(\theta\) únicamente toma valores para los cuales \(f(Y|\theta)\) es una función de densidad.
Al aplicar el método de la misma forma que lo anterior se obtiene los datos imputados y el siguinete summary:
imputed_data1 <- mice(base_na[,names(base_na) %in% columns],m = 5,
maxit = 1, method = "norm.boot",seed = 123,print=F)
complete_data1 <- mice::complete(imputed_data1)
summary(imputed_data1)
## Class: mids
## Number of multiple imputations: 5
## Imputation methods:
## Employment_Info_1 Employment_Info_6 Medical_History_1
## "norm.boot" "norm.boot" "norm.boot"
## PredictorMatrix:
## Employment_Info_1 Employment_Info_6 Medical_History_1
## Employment_Info_1 0 1 1
## Employment_Info_6 1 0 1
## Medical_History_1 1 1 0
Se escogerá el método que se ajuste mejor a los datos, esto se realiza a partir del gráfico de densidad.En esta sección se hace uso del paquete plotly que ayuda a tener gráficas interactivas para una mejor vizualizar de los datos.
El análisis se realizará para las siguientes variables:
En la siguiente gráfica se tiene la densidad de los datos originales sin considerar los valores faltantes y de los datos imputados por los dos métodos usados.
complete_data$method<-"cart"
complete_data1$method<-"boot"
base_na$method<-"original"
d<-rbind(complete_data,complete_data1,base_na)
p<-ggplot(d,aes(Employment_Info_1, fill=method))+geom_density(alpha=0.3)
ggplotly(p)
Al observar el gráfico se puede cloncluir que el método cart se ajusta mejor a los datos originales que el método bootstrap, a pesar de que las densidades son muy similares se diferencian el las colas.
Ahora, el proceso es el mismo para la variable Employment Info 6
p<-ggplot(d,aes(Employment_Info_6, fill=method))+geom_density(alpha=0.3)
ggplotly(p)
La diferencia de las densidades de los datos imputados en este caso es más visible el ajuste de cada método. En este caso, se mantiene que el método cart es mejor.
Por último, analizamos la variable Medical History 1 entonces:
p<-ggplot(d,aes(Medical_History_1, fill=method))+geom_density(alpha=0.3)
ggplotly(p)
Como en los resultados anteriores el método cart sigue siendo el que mejor se ajusta a los datos originales.
Del análisis se concluye que el método de Árboles de clasificación y regresión es mejor que el método de Regresión lineal usando bootstrap, pues los datos imputados se ajustan de mejor manera a los datos originales.
Entonces se porcede a remplazar los valores imputados en la base original:
base[,"Employment_Info_1"]<-complete_data[,"Employment_Info_1"]
base[,"Employment_Info_6"]<-complete_data[,"Employment_Info_6"]
base[,"Medical_History_1"]<-complete_data[,"Medical_History_1"]
#head(base)
#write.csv(base,"base_imputada.csv")
Finalmente, se observa que la base está libre de valores Na´s.
missmap(base)
Calafati, R. O. (2017). Estrategias para tratamiento de datos faltantes («missing data») en estudios con datos longitudinales. Universitat Oberta de Catalunya. http://openaccess.uoc.edu/webapps/o2/bitstream/10609/64085/6/romancalafatiTFG0617memoria.pdf
Enders, C. K. (2010). Applied Missing Data Analysis. The Guilford Press.
Li, C. (2018). Little’s Test of Missing Completely at Random. Northwestern University. https://cpb-us-w2.wpmucdn.com/blog.nus.edu.sg/dist/4/6502/files/2018/06/mcartest-zlxtj7.pdf
Little, R. J. A., & Rubin, D. B. (2002). Statistical Analysis with Missing Data (2.a ed.). Wiley.
van Buuren, S., & Groothuis-Oudshoorn, K. (2011). MICE: Multivariate Imputation by Chained Equations in R. Journal of Statistical Software, 45(3), 1. https://www.jstatsoft.org/article/view/v045i03