Carga de librerías
# Lectura de archivos
#install.packages("readr")
library(readr)
# Transformación BoxCox
#install.packages("MASS")
library(MASS)
# Manipulación de datos
#install.packages("tidyverse")
library(tidyverse)
# Separación de data
#install.packages("caTools")
library(caTools)
# Indicadores de rendimiento
#install.packages("Metrics")
library(Metrics)
# Modelo MARS
#install.packages("earth")
library(earth)
Lectura de base de datos
BDDenemdu <- read_delim("BDDenemdu_personas_2021_anual.csv",
delim = ";", escape_double = FALSE, trim_ws = TRUE)
Exploración de los datos
# Número de registros
dim(BDDenemdu)[1]
## [1] 361790
# Número de variables
dim(BDDenemdu)[2]
## [1] 151
# Tipo de variables
glimpse(BDDenemdu)
## Rows: 361,790
## Columns: 151
## $ area <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ~
## $ ciudad <dbl> 10150, 10150, 10150, 10150, 10150, 10150, 10150, 10150, 1~
## $ conglomerado <chr> "000802", "000802", "000802", "000802", "002101", "002101~
## $ panelm <chr> "016", "016", "016", "016", "002", "002", "002", "002", "~
## $ vivienda <chr> "02", "02", "02", "02", "02", "02", "07", "07", "07", "05~
## $ hogar <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ~
## $ p01 <chr> "01", "02", "03", "04", "01", "02", "01", "02", "03", "01~
## $ p02 <dbl> 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 2, 2, ~
## $ p03 <dbl> 58, 47, 27, 17, 84, 50, 48, 45, 23, 59, 62, 25, 23, 53, 3~
## $ p04 <dbl> 1, 2, 3, 3, 1, 3, 1, 2, 3, 1, 2, 3, 3, 1, 1, 1, 2, 3, 3, ~
## $ p05a <dbl> 2, 10, 10, 2, 10, 1, 10, 10, 10, 1, 1, 1, 2, 1, 1, 1, 1, ~
## $ p05b <dbl> 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1~
## $ p06 <dbl> 1, 1, 6, 6, 4, 3, 5, 5, 6, 1, 1, 6, 6, 3, 6, 1, 1, NA, NA~
## $ p07 <dbl> 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, NA, NA~
## $ p08 <dbl> NA, NA, NA, 1, NA, NA, NA, NA, NA, NA, NA, NA, 6, NA, NA,~
## $ p09 <dbl> 5, 11, 2, NA, 1, 5, 3, 3, 3, 2, 2, 2, NA, 5, 2, 2, 2, NA,~
## $ p10a <dbl> 9, 6, 9, 7, 6, 6, 9, 6, 7, 9, 9, 9, 9, 6, 10, 10, 9, NA, ~
## $ p10b <dbl> 3, 6, 6, 2, 6, 6, 4, 5, 3, 3, 3, 3, 5, 6, 2, 3, 5, NA, NA~
## $ p11 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p12a <dbl> 2, NA, 1, NA, NA, NA, 2, NA, NA, 1, 1, 1, 1, NA, 1, 1, 1,~
## $ p12b <dbl> NA, NA, 30910100, NA, NA, NA, NA, NA, NA, 21020204, 20910~
## $ p15 <dbl> 6, 6, 6, 6, 7, 7, 6, 6, 6, 7, 7, 7, 7, 6, 6, 6, 6, NA, NA~
## $ p15aa <dbl> 2, 2, 2, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ~
## $ p15ab <dbl> 30351, 30351, 30351, NA, NA, NA, NA, 170, 170, NA, NA, NA~
## $ cod_inf <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, NA, NA~
## $ p20 <dbl> 1, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 1, 2, 1, 1, 1, 1, NA, NA~
## $ p21 <dbl> NA, 12, 12, 12, 12, NA, 12, 12, 12, NA, 12, NA, 12, NA, N~
## $ p22 <dbl> NA, 2, 2, 2, 2, NA, 2, 2, 2, NA, 2, NA, 2, NA, NA, NA, NA~
## $ p23 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p24 <dbl> 50, NA, NA, NA, NA, 60, NA, NA, NA, 40, NA, 40, NA, 40, 4~
## $ p25 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p26 <dbl> 4, NA, NA, NA, NA, 1, NA, NA, NA, 1, NA, 1, NA, 1, 1, 5, ~
## $ p27 <dbl> 4, NA, NA, NA, NA, 4, NA, NA, NA, 4, NA, 4, NA, 4, 4, 4, ~
## $ p28 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p29 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p30 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p31 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p32 <dbl> NA, 11, 8, 11, 11, NA, 2, 2, 2, NA, 11, NA, 11, NA, NA, N~
## $ p33 <dbl> NA, NA, 20, NA, NA, NA, 4, 20, 8, NA, NA, NA, NA, NA, NA,~
## $ p34 <dbl> NA, 9, NA, 9, 12, NA, NA, NA, NA, NA, 12, NA, 9, NA, NA, ~
## $ p35 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p36 <dbl> NA, 4, NA, 3, 4, NA, NA, NA, NA, NA, 2, NA, 3, NA, NA, NA~
## $ p37 <dbl> NA, NA, 1, NA, NA, NA, 1, 2, 2, NA, NA, NA, NA, NA, NA, N~
## $ p38 <dbl> NA, NA, 5, NA, NA, NA, 2, NA, NA, NA, NA, NA, NA, NA, NA,~
## $ p39 <dbl> NA, NA, 20, NA, NA, NA, 8, NA, NA, NA, NA, NA, NA, NA, NA~
## $ p40 <dbl> 1629, NA, 8620, NA, NA, 8010, 4711, NA, NA, 8690, NA, 511~
## $ p41 <dbl> 7522, NA, 2261, NA, NA, 5414, 5223, NA, NA, 3255, NA, 311~
## $ p42 <dbl> 6, NA, 1, NA, NA, 2, 2, NA, NA, 6, NA, 2, NA, 1, 6, 2, 2,~
## $ p42a <dbl> 2, NA, NA, NA, NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, 2, ~
## $ p43 <dbl> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, NA, 2, NA, 1, NA, ~
## $ p44a <dbl> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, NA, 2, NA, 2, NA, ~
## $ p44b <dbl> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, NA, 2, NA, 2, NA, ~
## $ p44c <dbl> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, NA, 2, NA, 2, NA, ~
## $ p44d <dbl> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, NA, 1, NA, 1, NA, ~
## $ p44e <dbl> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, NA, 2, NA, 1, NA, ~
## $ p44f <dbl> NA, NA, NA, NA, NA, 1, NA, NA, NA, NA, NA, 1, NA, 1, NA, ~
## $ p44g <dbl> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, NA, 2, NA, 2, NA, ~
## $ p44h <dbl> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, NA, 2, NA, 2, NA, ~
## $ p44i <dbl> NA, NA, NA, NA, NA, 1, NA, NA, NA, NA, NA, 1, NA, 1, NA, ~
## $ p44j <dbl> NA, NA, NA, NA, NA, 1, NA, NA, NA, NA, NA, 1, NA, 1, NA, ~
## $ p44k <dbl> NA, NA, NA, NA, NA, 1, NA, NA, NA, NA, NA, 1, NA, 1, NA, ~
## $ p45 <dbl> 30, NA, NA, NA, NA, 18, NA, NA, NA, 15, NA, 3, NA, 7, 10,~
## $ p46 <dbl> 9, NA, NA, NA, NA, 1, NA, NA, NA, 6, NA, 1, NA, 1, 6, 1, ~
## $ p47a <dbl> 1, NA, NA, NA, NA, 1, NA, NA, NA, 1, NA, 2, NA, 2, 1, 1, ~
## $ p47b <dbl> 1, NA, NA, NA, NA, 20, NA, NA, NA, 1, NA, NA, NA, NA, 1, ~
## $ p48 <dbl> 2, NA, NA, NA, NA, 1, NA, NA, NA, 1, NA, NA, NA, NA, 3, 2~
## $ p49 <dbl> 1, NA, NA, NA, NA, 1, NA, NA, NA, 1, NA, NA, NA, NA, 1, 1~
## $ p50 <dbl> 2, NA, NA, NA, NA, 1, NA, NA, NA, 1, NA, 1, NA, 1, 1, 1, ~
## $ p51a <dbl> 40, NA, NA, NA, NA, 60, NA, NA, NA, 40, NA, 40, NA, 40, 4~
## $ p51b <dbl> 10, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p51c <dbl> 0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA~
## $ p52 <dbl> 4921, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,~
## $ p53 <dbl> 8331, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,~
## $ p54 <dbl> 6, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA~
## $ p54a <dbl> 2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA~
## $ p55 <dbl> 3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA~
## $ p56a <dbl> 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA~
## $ p56b <dbl> 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA~
## $ p57 <dbl> 2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA~
## $ p58 <dbl> 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA~
## $ p59 <dbl> 1, NA, NA, NA, NA, 1, NA, NA, NA, 5, NA, 5, NA, 1, 1, 1, ~
## $ p60a <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p60b <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p60c <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p60d <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p60e <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p60f <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p60g <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p60h <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p60i <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p60j <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p60k <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p61b1 <dbl> 2, 5, 5, 5, 5, 1, 5, 5, 5, 1, 5, 1, 2, 1, 1, 1, 1, NA, NA~
## $ p63 <dbl> 999999, NA, NA, NA, NA, NA, NA, NA, NA, 999999, NA, NA, N~
## $ p64a <dbl> 2, NA, NA, NA, NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, 2, ~
## $ p64b <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p65 <dbl> 999999, NA, NA, NA, NA, NA, NA, NA, NA, 999999, NA, NA, N~
## $ p66 <dbl> NA, NA, NA, NA, NA, 999999, NA, NA, NA, NA, NA, 999999, N~
## $ p67 <dbl> NA, NA, NA, NA, NA, 999999, NA, NA, NA, NA, NA, 999999, N~
## $ p68a <dbl> NA, NA, NA, NA, NA, 1, NA, NA, NA, NA, NA, 1, NA, 1, NA, ~
## $ p68b <dbl> NA, NA, NA, NA, NA, 999999, NA, NA, NA, NA, NA, 0, NA, 99~
## $ p69 <dbl> 999999, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p70a <dbl> 2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA~
## $ p70b <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p71a <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, NA, NA~
## $ p71b <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p72a <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, NA, NA~
## $ p72b <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 999999, NA, NA, N~
## $ p73a <dbl> 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, NA, NA~
## $ p73b <dbl> 200, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
## $ p74a <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, NA, NA~
## $ p74b <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p75 <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, NA, NA~
## $ p76 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ p77 <dbl> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, NA, NA~
## $ p78 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ sd01 <dbl> NA, NA, 2, NA, NA, NA, 2, 2, 2, NA, NA, NA, NA, NA, NA, N~
## $ sd021 <dbl> NA, NA, 2, NA, NA, NA, 2, 2, 2, NA, NA, NA, NA, NA, NA, N~
## $ sd022 <dbl> NA, NA, 2, NA, NA, NA, 2, 2, 2, NA, NA, NA, NA, NA, NA, N~
## $ sd023 <dbl> NA, NA, 1, NA, NA, NA, 1, 1, 1, NA, NA, NA, NA, NA, NA, N~
## $ sd024 <dbl> NA, NA, 1, NA, NA, NA, 1, 1, 1, NA, NA, NA, NA, NA, NA, N~
## $ sd025 <dbl> NA, NA, 2, NA, NA, NA, 2, 2, 2, NA, NA, NA, NA, NA, NA, N~
## $ sd026 <dbl> NA, NA, 2, NA, NA, NA, 2, 2, 2, NA, NA, NA, NA, NA, NA, N~
## $ sd027 <dbl> NA, NA, 2, NA, NA, NA, 2, 2, 2, NA, NA, NA, NA, NA, NA, N~
## $ sd028 <dbl> NA, NA, 2, NA, NA, NA, 2, 2, 2, NA, NA, NA, NA, NA, NA, N~
## $ sd029 <dbl> NA, NA, 2, NA, NA, NA, 2, 2, 2, NA, NA, NA, NA, NA, NA, N~
## $ sd0210 <dbl> NA, NA, 2, NA, NA, NA, 2, 2, 2, NA, NA, NA, NA, NA, NA, N~
## $ sd0211 <dbl> NA, NA, 2, NA, NA, NA, 2, 2, 2, NA, NA, NA, NA, NA, NA, N~
## $ sd03 <dbl> NA, NA, 2, NA, NA, NA, 1, 9, 9, NA, NA, NA, NA, NA, NA, N~
## $ ced01a <dbl> 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, ~
## $ estrato <chr> "2712", "2712", "2712", "2712", "2713", "2713", "2713", "~
## $ fexp <dbl> 7.918958e+14, 7.918958e+14, 7.918958e+14, 7.918958e+14, 7~
## $ nnivins <dbl> 5, 4, 5, 4, 4, 4, 5, 4, 4, 5, 5, 5, 5, 4, 5, 5, 5, NA, NA~
## $ ingrl <dbl> 999999, NA, NA, NA, NA, 999999, NA, NA, NA, 999999, NA, 9~
## $ ingpc <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ condact <dbl> 6, 9, 7, 9, 9, 6, 7, 7, 7, 6, 9, 6, 9, 6, 6, 6, 6, 0, 0, ~
## $ empleo <dbl> 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, ~
## $ desempleo <dbl> 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~
## $ secemp <dbl> 1, NA, NA, NA, NA, 1, NA, NA, NA, 1, NA, 1, NA, 1, 1, 1, ~
## $ grupo1 <dbl> 7, NA, NA, NA, NA, 5, NA, NA, NA, 3, NA, 3, NA, 4, 2, 2, ~
## $ rama1 <dbl> 3, NA, NA, NA, NA, 14, NA, NA, NA, 17, NA, 8, NA, 15, 17,~
## $ prov <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ~
## $ dominio <dbl> 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, ~
## $ pobreza <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ epobreza <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N~
## $ upm <chr> "010150000802", "010150000802", "010150000802", "01015000~
## $ id_vivienda <chr> "0101500008020160207", "0101500008020160207", "0101500008~
## $ id_hogar <chr> "01015000080201602107", "01015000080201602107", "01015000~
## $ id_persona <chr> "0101500008020160210107", "0101500008020160210207", "0101~
## $ periodo <dbl> 202107, 202107, 202107, 202107, 202101, 202101, 202101, 2~
## $ mes <chr> "07", "07", "07", "07", "01", "01", "01", "01", "01", "06~
Variable objetivo
# Estadísticos principales de la variable ingreso laboral
summary(BDDenemdu$ingrl)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -1 150 350 11954 600 999999 215257
# Diagrama de caja de la variable ingreso laboral
boxplot(BDDenemdu$ingrl, horizontal = TRUE)
# Histograma de la variable ingreso laboral
hist(BDDenemdu$ingrl, freq = FALSE, main = "", xlab = "")
Imputación de valores atípicos
# Se eliminan registros faltantes y no positivos
df <- BDDenemdu
df <- df[!is.na(df$ingrl),]
df <- df[df$ingrl > 0,]
# Se eliminan registros con ingreso laboral superiores a los $3K
df[df$ingrl > 3000,] %>% nrow()
## [1] 2733
df3k <- df[df$ingrl < 3000,]
# Se aplica una transformación de BoxCox con lambda (l = 0) - se puede optimizar el parámetro
df3k$ingrl <- log(df3k$ingrl)
df <- df3k
# Distribución de la variable objetivo
summary(df$ingrl)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.000 5.136 5.900 5.696 6.392 8.006
# Gráfico de cajas
boxplot(df$ingrl, horizontal = TRUE, main = "Diagrama de cajas ingreso laboral transformado")
# Histograma
hist(df$ingrl, freq = FALSE, main = "Histogrmama ingreso laboral transformado", xlab = "")
# Función de densidad
dx <- density(df$ingrl)
plot(dx, lwd = 1,
main = "Funcion de densidad de la variable ingreso laboral tranformado")
Selección de variables explicativas
Inicialmente se trabajará con una muestra de variables sociodemográficas tomadas con referencia del trabajo de Fernández F. Modelo de estimación de ingresos para clientes poco o nada vinculados con ABANCA, 2018. Adicional, únicamente con aquellas variables que no presentes valores faltantes para obtener un mejor ajuste en el modelo.
Las variables a probar en el modelo son las siguientes:
p02: Sexop03: Edadp06: Estado civilp10a: Nivel de instrucciónp45: Años que trabajap44j: Recibe 13er sueldop44k: Recibe 14to sueldop44g: Recibe seguro médicop44f: Recibe seguro socialp40: Rama de actividadp50: Número de trabajosp51a: Horas de trabajo principal# Base para modelamiento
df <- df[,c("id_persona", "p02", "p03", "p06", "p10a", "p45", "p44j", "p44k",
"p44g","p44f","p40","p50","p51a", "ingrl")]
# Tratamiento de valores faltantes
# Se elimina los NA de la variable estado civil p06 al tener poca representatividad
df <- df %>% filter(!is.na(p06))
# Se elimina los valores faltantes en las variables Recibe 13er sueldo, Recibe 14to sueldo,
# Recibe seguro social al desconocer la categoría de referencia y sí al tratar de reemplazar
# los valores por una categoría en específico se provocaría un desbalanceo en la muestra
df <- df %>% filter(!is.na(p44j))
# Tratamiento del tipo de datos
# Sexo es una variable cualitativa
round(prop.table(table(df$p02)),2)
##
## 1 2
## 0.62 0.38
df$p02 <- factor(df$p02, levels = c(1, 2), labels = c("1","2"))
# Estado civil es una variable cualitativa
round(prop.table(table(df$p06)),2)
##
## 1 2 3 4 5 6
## 0.31 0.07 0.04 0.02 0.23 0.33
df$p06 <- factor(df$p06, levels = c(1,2,3,4,5,6), labels = c("1","2","3","4","5","6"))
# Nivel de instrucción es una variable cualitativa
round(prop.table(table(df$p10a)),3)
##
## 1 2 4 5 6 7 8 9 10
## 0.010 0.001 0.187 0.034 0.292 0.127 0.041 0.265 0.043
df$p10a <- factor(df$p10a, levels = c(1,2,3,4,5,6,7,8,9,10), labels = c("1","2","3","4","5","6","7","8","9","10"))
# Recibe 13er sueldo es una variable cualitativa
round(prop.table(table(df$p44j)),2)
##
## 1 2
## 0.54 0.46
df$p44j <- factor(df$p44j, levels = c(1,2), labels = c("1","2"))
# Recibe 14to sueldo es una variable cualitativa
round(prop.table(table(df$p44k)),2)
##
## 1 2
## 0.54 0.46
df$p44k <- factor(df$p44k, levels = c(1,2), labels = c("1","2"))
# Recibe seguro médico una variable cualitativa
round(prop.table(table(df$p44g)),2)
##
## 1 2
## 0.01 0.99
df$p44g <- factor(df$p44g, levels = c(1,2), labels = c("1","2"))
# Recibe seguro social una variable cualitativa
round(prop.table(table(df$p44f)),2)
##
## 1 2
## 0.55 0.45
df$p44f <- factor(df$p44f, levels = c(1,2), labels = c("1","2"))
# Rama de actividad es cualitativa
df$p40 <- as.character(df$p40)
# Nombre de las variables
names(df) <- c("idPersona", "sexo", "edad", "estadoCivil", "nivInstruccion", "aniosTrabajando",
"recibe13Sueldo", "recibe14Sueldo", "recibeSeguroMedico", "recibeSeguroSocial",
"actividad", "numTrabajos", "horasTrabajo", "ingreso")
# Resumen de variables
summary(df)
## idPersona sexo edad estadoCivil nivInstruccion
## Length:75948 1:47326 Min. :12.00 1:23736 6 :22168
## Class :character 2:28622 1st Qu.:28.00 2: 5603 9 :20141
## Mode :character Median :37.00 3: 3034 4 :14238
## Mean :37.91 4: 1234 7 : 9665
## 3rd Qu.:47.00 5:17338 10 : 3230
## Max. :89.00 6:25003 8 : 3102
## (Other): 3404
## aniosTrabajando recibe13Sueldo recibe14Sueldo recibeSeguroMedico
## Min. : 0.000 1:40677 1:40686 1: 817
## 1st Qu.: 2.000 2:35271 2:35262 2:75131
## Median : 6.000
## Mean : 9.625
## 3rd Qu.:15.000
## Max. :70.000
##
## recibeSeguroSocial actividad numTrabajos horasTrabajo
## 1:41530 Length:75948 Min. :1.000 Min. : 1.00
## 2:34418 Class :character 1st Qu.:1.000 1st Qu.: 40.00
## Mode :character Median :1.000 Median : 40.00
## Mean :1.063 Mean : 39.37
## 3rd Qu.:1.000 3rd Qu.: 40.00
## Max. :2.000 Max. :120.00
##
## ingreso
## Min. :0.000
## 1st Qu.:5.704
## Median :6.116
## Mean :6.091
## 3rd Qu.:6.646
## Max. :8.006
##
Base de entrenamiento y validación
set.seed(12345)
# Sets para entrenamiento y validación
sample <- sample.split(df$idPersona, SplitRatio = .75)
# Base de entrenamiento
train <- subset(df, sample == TRUE)
# Base de validación
test <- subset(df, sample == FALSE)
Modelo MARS (Multivariate Adaptive Regression Splines)
# Estimación del modelo
marsModel <- earth(ingreso ~ edad + aniosTrabajando + horasTrabajo + sexo
+ recibe13Sueldo + estadoCivil
+ numTrabajos + nivInstruccion, data = train)
# Estadísticos generales
marsModel
## Selected 15 of 15 terms, and 11 of 20 predictors
## Termination condition: RSq changed by less than 0.001 at 15 terms
## Importance: recibe13Sueldo2, horasTrabajo, nivInstruccion10, ...
## Number of terms at each degree of interaction: 1 14 (additive model)
## GCV 0.2465879 RSS 14031.6 GRSq 0.6203334 RSq 0.6207066
# Coeficientes estimados
marsModel$coefficients
## ingreso
## (Intercept) 6.3794855790
## recibe13Sueldo2 -0.6048215256
## h(horasTrabajo-40) 0.0055778876
## h(40-horasTrabajo) -0.0383522880
## nivInstruccion10 0.7069858395
## nivInstruccion9 0.3284876862
## h(edad-35) -0.0008341021
## h(35-edad) -0.0151703175
## nivInstruccion4 -0.1382061875
## sexo2 -0.0775922999
## nivInstruccion8 0.1950333263
## h(aniosTrabajando-3) 0.0007381790
## h(3-aniosTrabajando) -0.0315627932
## numTrabajos 0.1241224623
## estadoCivil6 -0.0641367358
# Error cuadrático medio
actual <- test$ingreso
marsResults <- predict(marsModel, test)
cat("Error cuadrático medio: ", rmse(marsResults, actual))
## Error cuadrático medio: 0.4907597
Estadísticos de desempeño
Las medidas estadísticas que el modelo estimado presentan son:
Se puede observar que los estadísticos que presenta el modelo son aceptables.
Adicional, se han calculado rangos del ingreso laboral medio y su estimación:
rank <- data.frame(cbind(exp(actual), exp(marsResults)))
names(rank) <- c("ingresoReal", "ingresoEstimado")
rank <- rank %>% mutate(rangoIngresoReal = case_when(
between(ingresoReal, 0, 490) ~ "[0, 490)",
between(ingresoReal, 490, 690) ~ "[490, 690)",
between(ingresoReal, 690, 1000) ~ "[690, 1000)",
between(ingresoReal, 1000, 1200) ~ "[1000, 1200)",
between(ingresoReal, 1200, 1600) ~ "[1200, 1600)",
ingresoReal > 1600 ~ "[1600, 3000)"
),
rangoIngresoEstimado = case_when(
between(ingresoEstimado, 0, 490) ~ "[0, 490)",
between(ingresoEstimado, 490, 690) ~ "[490, 690)",
between(ingresoEstimado, 690, 1000) ~ "[690, 1000)",
between(ingresoEstimado, 1000, 1200) ~ "[1000, 1200)",
between(ingresoEstimado, 1200, 1600) ~ "[1200, 1600)",
ingresoEstimado > 1600 ~ "[1600, 3000)",
)
)
rankMedioReal <- rank %>% group_by(rangoIngresoReal) %>% summarise(ingresoRealMedio = mean(ingresoReal))
rankMedioEstimado <- rank %>% group_by(rangoIngresoEstimado) %>% summarise(ingresoEstimadoMedio = mean(ingresoEstimado))
rankMedio <- cbind(rankMedioReal, rankMedioEstimado)
rankMedio <- rankMedio[, c("rangoIngresoReal", "ingresoRealMedio", "ingresoEstimadoMedio")]
rankMedio <- rankMedio %>% mutate(orden_rango = case_when(rangoIngresoReal == "[0, 490)" ~ 1,
rangoIngresoReal == "[490, 690)" ~ 2,
rangoIngresoReal == "[690, 1000)" ~ 3,
rangoIngresoReal == "[1000, 1200)" ~ 4,
rangoIngresoReal == "[1200, 1600)" ~ 5,
rangoIngresoReal == "[1600, 3000)" ~ 6,
)) %>% arrange(orden_rango)
rankMedio
## rangoIngresoReal ingresoRealMedio ingresoEstimadoMedio orden_rango
## 1 [0, 490) 300.2756 275.1556 1
## 2 [490, 690) 575.8452 605.5678 2
## 3 [690, 1000) 835.0622 828.5498 3
## 4 [1000, 1200) 1098.0786 1099.5683 4
## 5 [1200, 1600) 1366.1162 1309.6130 5
## 6 [1600, 3000) 2048.1458 1605.8369 6
El gráfico anterior muestra el perfil de ingreso que genera el modelo, se puede observar que es preciso para los rangos de ingreso medio. Sin embargo, para el rango de entre \([1600, 3000)\) presenta una subestimación, es decir, el ingreso estimado es menor a $2000.
Conclusiones