Prediciendo el número de hijos de los hogares colombianos

Informe

Introducción

En la actualidad, debido a la globalización es importante para las empresas conocer a sus clientes, la tecnología, sin duda ha permitido recaudar volúmenes enormes de información, sin embargo, en muchas ocasiones precisamente la información requerida por una empresa es difícil de obtener o representa información sensible para los usuarios, ya que invade su privacidad. No obstante, con los avances en analítica se han creado herramientas para lograr obtener la información necesaria de los usuarios sin invadir su intimidad y está ha podido utilizarse para estimar valores sobre el resto de la población, aun sin tener que preguntar directamente sobre la misma.

Entre los datos que en algunos contextos pueden ser censurados u omitidos está el número de hijos en un hogar, lo que hace que sea una variable de la que no se dispone directamente; por lo tanto el problema en particular en el que se está interesado es la predicción del número de hijos en base a las características de los hogares colombianos.

Se decidió abordar este problema como un problema de clasificación (aprendizaje supervisado). Para esto se tuvo en cuenta los siguiente:

Se realizó una buena investigación y contextualización del conjunto de datos que fueron obtenidos de la ECV realizada por el DANE en el año 2019, mediante este se tuvo la oportunidad de establecer el número de hijos, a partir de, la combinación de algunas variables presentes en un conjunto de datos particular abordado en la encuesta, además de seleccionar las variables más relevantes para realizar un análisis y la modelación.

Se procedió a la selección de variables, las cuales posteriormente fueron unidas mediante indicadores de hogares. Este procedimiento fue realizado de manera muy cuidadosa para no obtener información incorrecta, después de este paso se llegó a una base de datos con las variables que los investigadores consideraron de interés.

Previo a lo anterior, se procedió a realizar un análisis descriptivo sobre el conjunto de datos, que ayudaran a una mejor comprensión de las variables y a seleccionar cuales de estas eran más relevantes para predecir el número de hijos, se realizaron gráficos y demás análisis.

Como paso siguiente se usaron técnicas estadísticas para la selección de variables mediante la formulación de modelos, los cuales en su mayoría coincidieron con las variables seleccionadas mediante el análisis descriptivo.

Después de seleccionar las variables, se obtuvo un conjunto de datos con menos atributos, pero con el mismo número de registros, y asi se empezó a modelar el número de hijos como un problema de clasificación, donde cada nivel de la variable respuesta es una categoría. Dado que el número de hijos variaba en el rango de 0 a 14, se decido dejar como categorías 0, 1, 2, 3, 4 y 5 o más.

Los modelos seleccionados fueron considerados como los más adecuados para este problema en particular y son populares en el mundo del aprendizaje estadístico. Se realizaron ajustes con cada uno y se evaluó su rendimiento mediante validación cruzada (Calculando tasas de acierto y error).

Después de ajustar varios modelos, se analizó la posibilidad de encontrar el mismo resultado con menos variables, encontrando que se obtenía la misma tasa de acierto, aunque, el número de atributos utilizados era menor; por lo tanto, se decidió nuevamente hacer una reducción del conjunto de datos, de tal manera que se obtuvieron modelos más parsimoniosos (Buenos resultados con menos variables) llegando finalmente a modelos con cinco variables.

De los modelos ajustados inicialmente se consideraron los cuatro mejores. Posteriormente estos modelos se ponen en competencia mediante distintas muestras aleatorias, divididas en conjunto de entrenamiento y validación; de tal manera, que el mejor modelo sea aquel que obtenga mejores resultados en el conjunto de validación en las diferentes muestras.

Bosques Aleatorios (Random forest) resultó ser el mejor después de este procedimiento, teniendo la tasa de aciertos más alta entre los modelos probados y siendo uno de los más rápidos en cuanto al tiempo de predicción.

Para finalizar, se ajustó el mejor modelo con todo el conjunto de datos, con el fin de generar mejores predicciones por el hecho de contar con un mayor número de información y se agregó el modelo en una aplicación web (Aplicación Número de hijos) que permite la interacción de los usuarios, esto muestra su potencial para predecir el número de hijos de un hogar colombiano según la estructura del mismo.

Todos los recursos utilizados para la elaboración del informe y la aplicación se encuentran en un repositorio de github que pueden visitar a continuación…..Repositorio del proyecto Número de hijos de los hogares Colombianos

Retos

  • Contextualizar la base de datos.
  • Seleccionar las variables.
  • Construir la variable número de hijos.
  • Organizar la base de datos con variables que contribuyan de manera significativa a la solución del problema.
  • Encontrar modelos que se ajusten a las necesidades del conjunto de datos.
  • Seleccionar una solución óptima tanto para los investigadores como para los usuarios de la app.

Contextualización del conjunto de datos:

El número de hijos en un hogar es una variable muy simple y poco estudiada en algunos contextos, por eso los volúmenes de datos que se encuentran en la web muchas veces no disponen de este tipo de información, pero para entidades como inmobiliarias, empresas crediticias, etc; puede serles de sumo interés, por ello, bajo trabajos de investigación se llega a la conclusión de que estas variables pueden ser deducidas a partir de otras que siguen en el mismo contexto, en este caso particular el número de hijos puede ser deducida a partir de conjuntos de datos relacionados con información acerca de los hogares del país, por lo tanto, una de las bases de datos que se considera tienen más relación con las viviendas y hogares de Colombia es la encuesta de Calidad de vida, donde la más actualizada hasta la fecha es la realizada en el año 2019.

La Encuesta de Calidad de Vida (ECV) es una investigación que realiza el DANE, con el objetivo de recoger información sobre diferentes aspectos y dimensiones del bienestar de los hogares, incluyendo aspectos como el acceso a bienes y servicios públicos, privados o comunales, salud, educación, cuidado de niños y niñas menores de 5 años, entre otros. Esta información posibilita efectuar análisis posteriores de los factores que explican los diferentes niveles de vida existentes en la población colombiana.

Por ello mediante este conjunto de datos que tiene un gran volumen, se intenta extraer aquellas variables que se consideran más representativas para intentar predecir el número de hijos que tiene cada uno de los hogares; antes de ello, se debe definir para esta investigación que es un hogar y que es el número de hijos, para realizar todos los análisis posteriores en función de esta variable (Número de hijos en el hogar).

Definiciones importantes

Usuario

Inmobiliarias, empresas crediticias, en las cuales el número de hijos es una información sensible, ya que esto puede suponerse como un impedimento ya sea a la hora de conseguir o rentar apartamento, o para conseguir préstamos; debido a que, se concibe que el mantenimiento de los hijos es elevado y este sube cuantos más hijos posee el prestatario, por lo que resulta más complicado para los padres de familia acceder a los mismos.

Agencias o constructoras inmobiliarias en ocasiones tienen mucha información histórica de los clientes, sobretodo de los jefes de hogar, obteniendo así información relevante de las características de un hogar. En base a estas características podemos predecir el número de hijos del mismo, esta información puede ser utilizada por dichas empresas para lanzar nuevos proyectos y ofrecer atención más personalizada a sus usuarios.

Adicionalmente, algunas empresas que facilitan el arriendo como intermediarios pueden tener políticas de arriendo como el hecho de que no se admiten hijos en los hogares, esto es común en residencias estudiantiles, entre otros.

Hogar

Según el DANE se entiende como hogar a una persona o grupo de personas que ocupan la totalidad o parte de una vivienda y que se han asociado para compartir su lugar de descanso, alimentos y demás necesidades básicas (si se trata de hogar-unidad doméstica) . Pueden ser familiares o no entre sí.

Un hogar no puede dividirse en más de una vivienda, pero dentro de cada vivienda, puede haber más de un hogar, conformado por una o más personas con o sin vínculos de parentesco.

Número de hijos

Se define el número de hijos de acuerdo con los hogares colombianos promedio, definidos por el DANE, en los cuales se tienen:

  • Parejas con hijos.
  • Una persona sola.
  • Padre o madre y sus hijos.
  • Parejas sin hijos.
  • Hogar extenso-compuesto, definido como hogares nucleares (alguna de las opciones anteriormente mencionadas) más otros parientes.

Se muestra a continuación una imagen que ejemplifica mejor lo antes mencionado:

En base a esto se considera como el número de hijos, a los hijos, hijastros y nietos del jefe del hogar, sin discriminar por edad, ya que está es la forma que en general funciona mejor, en base a la mayoría de estructuras de los hogares en Colombia.

En casos generales funciona esta estructura ya que en la mayoría de hogares cuenta con padres y si estos no están presentes, los abuelos de los hijos lo están, cuando se considera que hay varios grupos familiares en una misma vivienda, como lo son por ejemplo, varios hermanos con sus respectivos hijos, estos se dividirán en diferentes hogares; ya que son varios núcleos familiares en una misma vivienda, los cuales deben ser tomados como hogares de manera independiente, por lo tanto, estructuras como estas no sesgan la elección de la variable número de hijos. Además, cabe aclarar que la encuesta de calidad de vida hace esta misma división, ya que en una misma vivienda se ven presentes varios hogares(siendo 5 el máximo), por lo tanto, esta variable fue seleccionada con los hijos/hijastros y nietos del jefe del hogar; en base a la estructura de la encuesta de calidad de vida y en la perspectiva de los investigadores.

Materiales

Variables preselecionadas

Características y composición del hogar.

Compuesta por 46 variables de las cuales se escogieron

Código Nombre Pregunta
P6040 Genero Sexo: 1 Hombre 2 Mujer
P6040 Edad ¿Cuántos años cumplidos tiene … ?
P6051 - ¿Cuál es el parentesco de ___ con el jefe o la jefa de este hogar? 1 Jefe (a) del hogar 2 Pareja, esposo (a), cónyuge, compañero(a) 3 Hijo(a) hijastro(a) 4 Nieto (a) 5 Padre, madre, padrastro y madrastra 6 Suegro o suegra 7 Hermano (a), hermanastro (a) 8 Yerno, nuera 9 Otro pariente del jefe(a) 10 Empleado(a) del servicio doméstico 11 Parientes del servicio doméstico 12 Trabajador 13 Pensionista 14 Otro pariente
P5502 Estado_civil Actualmente el jefe del hogar: 1 No está casado(a) y vive en pareja hace menos de dos años 2 No está casado(a) y vive en pareja hace dos años o más 3 Está viudo(a) 4 Está separado(a) o divorciado(a) 5 Está soltero(a) 6 Está casado(a)
P756 Lugar_nacimiento ¿Dónde nació el jefe del hogar? 1 En este municipio 2 En otro municipio 3 En otro país
P6081 Vive_hogar_padre ¿El padre del jefe del hogar vive en este hogar?
P6087 Educacion_padre ¿Cuál es o fue el nivel de educación más alto alcanzado por el padre del jefe del hogar?
P6083 Vive_hogar_madre ¿La madre del jefe del hogar vive en este hogar?
P6088 Educacion_madre ¿Cuál es o fue el nivel de educación más alto alcanzado por la madre del jefe del hogar?
P6080 Etnia De acuerdo con su cultura, pueblo o rasgos físicos, _____ es o se reconoce como: 1 Indígena 2 Gitano (a) (Rom) 3 Raizal del archipiélago de San Andrés, Providencia y Santa Catalina 4 Palenquero (a) de San Basilio 5 Negro (a), mulato (a) (afrodescendiente), afrocolombiano(a) 6 Ninguno de los anteriores

Condiciones de vida del hogar y tenencia de bienes (programas).

Compuesta por 8 variables de las cuales se escogió:

Código Nombre Pregunta
P784S4A3 Num_subsidios ¿Cuántos miembros del hogar reciben subsidios?

Datos de la vivienda.

Compuesta por 35 variables de las cuales se escogieron:

Código Nombre Pregunta
P1070 Tipo_vivienda Tipo de vivienda: 1 Casa 2 Apartamento 3 Cuarto(s) 4 Vivienda tradicional indigena 5 Otro (carpa, contenedor, vagón, embarcación, cueva, refugio natural, etc
P4015 Material_pisos Material predominante de los pisos: 1 Alfombra o tapete de pared a pared 2 Madera pulida y lacada, parqué 3 Mármol 4 Baldosa, vinilo, tableta, ladrillo, laminado 5 Madera burda, tabla, tablón, otro vegetal 6 Cemento, gravilla 7 Tierra, arena
P8520S1 Energia_electrica ¿La vivienda cuenta con energía eléctrica? 1 Sí 2 No
P8520S1A1 Estrato Estrato para tarifa de la energía eléctrica: 1 Bajo - Bajo 2 Bajo 3 Medio - Bajo 4 Medio 5 Medio - Alto 6 Alto 8 Planta eléctrica 9 No conoce el estrato o no cuenta con recibo de pago. 0 Recibos sin estrato o el servicio es pirata
P8520S5 Acueducto ¿La vivienda cuenta con acueducto? 1 Sí 2 No
P8520S3 Alcantarillado ¿La vivienda cuenta con alcantarillado? 1 Sí 2 No
P8520S4 Basuras_semana ¿Cuenta con servicio de Recolección de basuras? 1 Sí 2 No

Educación.

Compuesta por 58 variables de las cuales se escogieron:

Código Nombre Pregunta
P8586 Estudia ¿El jefe del hogar actualmente estudia? (asiste al preescolar, escuela, colegio o universidad) 1 Sí 2 No
P8587 Nivel_educativo ¿Cuál es el nivel educativo más alto alcanzado por el jefe del hogar y el último año o grado aprobado en este nivel? 1 Ninguno 2 Preescolar 3 Básica Primaria (1º - 5º) 4 Básica secundaria (6º–9º) 5 Media (10º–13º) 6 Técnico sin título 7 Técnico con título 8 Tecnológico sin título 9 Tecnológico con título 10 Universitario sin titulo 11 Universitario con titulo 12 Postgrado sin titulo 13 Postgrado con titulo

Salud.

Compuesta por 103 variables de las cuales se escogieron:

Código Nombre Pregunta
P6090 Afiliado ¿El jefe del hogar está afiliado (a), es cotizante o es beneficiario (a) de alguna entidad de seguridad social en salud? (Entidad promotora de salud [EPS] o entidad promotora de salud subsidiada EPS-S) 1 Sí 2 No 9 No sabe, no informa
P6127 Salud_general El estado de salud del jefe del hogar en general, es: 1 Muy bueno 2 Bueno 3 Regular 4 Malo

Servicios del hogar.

Compuesta por 64 variables de las cuales se escogieron:

Código Nombre Pregunta
P5666 Gas_natural ¿En este hogar tienen servicio de Gas Natural conectado a red pública? 1 Sí 2 No
P5305 Telefonia_fija ¿En este hogar tienen servicio telefónico fijo? 1 Sí 2 No
I_HOGAR Ingresos_hogar Ingreso Mensual Total del Hogar

Tenencia y financiación de la vivienda que ocupa el hogar.

Compuesta por 20 variables de las cuales se escogieron:

Código Nombre Pregunta
P5095 Contrato_vivienda ¿La vivienda ocupada por este hogar es? 1. Propia, totalmente pagada 2. Propia, la están pagando 3. En arriendo o subarriendo 4. Con permiso del propietario, sin pago alguno (usufructuario) 5. Posesión sin título (ocupante de hecho) 6. Propiedad colectiva

Uso de energéticos del hogar.

Compuesta por 45 variables de las cuales se escogieron:

Código Nombre Pregunta
P5018 Ultimo_pago_energia ¿Cuánto pagaron EL MES PASADO o la última vez por la electricidad consumida?
P5018S1 - ¿A cuántos meses corresponde el pago de la última vez por la electricidad consumida?

Variables construidas a partir de otras.

Código Nombre Variables utilizadas
P5018S Pago_mes_energia Esta variable fue creada dividiendo P5018/P5018S1 con el fin de obtener el pago mensual de electricidad
Num_integrantes Num_integrantes Esta variable fue creada sumando 1 unidad cada vez que el número de ORDEN cambiaba
Num_hijos Num_hijos Esta variable fue creada sumando 1 cada vez que la pregunta código P6051 toma el valor de 3 o 4 correspondiente a hijo o nieto

Metodología

Preprocesamiento de los datos

Creación de la variable número de hijos

Debido a que la variable de interés (Número de hijos) no aparece de manera explícita, se llevó a cabo un proceso de construcción de la misma. Esto fue posible gracias a algunas de las variables de la base de datos Características y composición del hogar, presente en la ECV(2019) que permiten conocer la relación de cada individuo con el jefe del hogar.

Como primer paso se realiza la lectura de las bases de datos:

Caracteristicas_hogar_personas <- read.table("Caracteristicas y composicion del hogar.csv", sep = ";", header = T)

Debido a que la variable P6051 muestra el parentesco de los integrantes de la familia con el jefe de hogar, solo será utilizada para la creación de la variable número de hijos, es decir, no se tiene en cuenta como covariable para el ajuste de modelos:

Selección de las variables que permitiran la creación de la variable respuesta número de hijos a partir del conjunto de datos Caracteristicas y composición del hogar:

#Selección de las variables necesarias
aux_creacion_respuesta<-Caracteristicas_hogar_personas[,c("ï..DIRECTORIO","SECUENCIA_P","P6051")]

Para obtener el número de hijos por hogar se filtran las filas, si tienen una relacion de hijo/hija/hijastro(a) o nieto/nieta con el jefe de hogar y se cuenta el número de hijos por hogar. Los hogares se describen con el código único de ï..DIRECTORIO, SECUENCIA_P.

El conjunto de datos presente a continuación solo contiene a los hogares con hijos:

require(tidyverse)
require(dplyr)

# P6051 = 3 : Hijo/hija/hijastro(a)
# P6051 = 4 : Nieto/nieta

num_hijos <- aux_creacion_respuesta %>%
  filter(P6051 == 3 | P6051 == 4)%>% #filtro
  group_by(ï..DIRECTORIO, SECUENCIA_P)%>% # agrupando por el identificador del hogar
  count(SECUENCIA_P) # Conteo del número de hijos por hogar
ï..DIRECTORIO SECUENCIA_P n
7120001 1 1
7120002 1 7
7120009 1 1
7120010 1 3
7120016 1 2
7120018 1 2

El número de hogares que tiene al menos un hijo es de: 59575 hogares.

A continuación, se procede a calcular el número de integrantes que pertenecen a cada hogar:

require(dplyr)
num_integrantes <- Caracteristicas_hogar_personas %>%
  group_by(ï..DIRECTORIO, SECUENCIA_P) %>% # agrupación por el indicador de los hogares
  count(SECUENCIA_P) #Conteo del número de integrantes por hogar
ï..DIRECTORIO SECUENCIA_P n
7120001 1 4
7120002 1 10
7120005 1 2
7120006 1 3
7120007 1 3
7120008 1 1

El número de hogares es 93993.

Finalmente, con la función merge se obtiene el número de hijos en cada hogar, uniendo las bases de datos num_integrantes y num_hijos como sigue:

  • el all.x = TRUE hace que se conserven todos los identificadores de los hogares que tienen integrantes y no sólo de los que poseen hijos.
num_hijos_final <- merge(num_integrantes, num_hijos, by =c("ï..DIRECTORIO","SECUENCIA_P"), all.x=TRUE) # merge de las dos bases de datos creadas anteriormente.

num_hijos_final$n.y[is.na(num_hijos_final$n.y)] <- 0 # Los datos faltantes indican que el hogar no tiene hijos

colnames(num_hijos_final) <- c("ï..DIRECTORIO","SECUENCIA_P", "Num Integrantes", "Num Hijos")
ï..DIRECTORIO SECUENCIA_P Num Integrantes Num Hijos
7120001 1 4 1
7120002 1 10 7
7120005 1 2 0
7120006 1 3 0
7120007 1 3 0
7120008 1 1 0
7120009 1 2 1
7120010 1 5 3
7120013 1 4 0
7120016 1 3 2

Selección de variables

Como paso siguiente se realizó de manera exhaustiva en cada una de las bases de la ECV, una preselección de covariables que a criterio de los investigadores, podrían tener alguna relación con la variable respuesta. Con la información anterior se procede a construir la base de datos para el paso siguiente.

A continuación se muestra la base que se obtuvo con las variables preseleccionadas que aparecen listadas en la contextualización de los datos:

# Características del hogar

Caracteristicas_hogar_personas <- read.table("Caracteristicas y composicion del hogar.csv", sep = ";", header = T)
Caracteristicas_hogar_personas<-Caracteristicas_hogar_personas[,c("ï..DIRECTORIO","SECUENCIA_P","ORDEN","P6020", "P6040","P6051", "P5502", "P756","P6081", "P6087","P6083","P6088","P6080")]

# Condiciones de vida del hogar y tenencia de bienes (programas)

condiciones_de_vida <- read.table("Condiciones de vida del hogar y tenencia de bienes (programas).csv", sep=";", header = T)
condiciones_de_vida <- condiciones_de_vida[, c("ï..DIRECTORIO","SECUENCIA_ENCUESTA","ORDEN","P784S4A3")]

# Datos de la vivienda

Datos_vivienda <- read.table("Datos de la vivienda.csv", sep = ";", header = T)
Datos_vivienda<-Datos_vivienda[,c("ï..DIRECTORIO","SECUENCIA_P","ORDEN","CANT_HOGARES_VIVIENDA","P1070","P4015","P8520S1","P8520S1A1","P8520S5","P8520S3", "P8520S4A1")]

# Educación

Educacion<- read.table("Educacion.csv", sep = ";", header = T)
Educacion<-Educacion[,c("ï..DIRECTORIO","SECUENCIA_P","ORDEN","P8587","P8586")]

# Fuerza de trabajo 

fuerza_trabajo <- read.table("Fuerza de trabajo.csv", sep=";", header = T)
fuerza_trabajo <- fuerza_trabajo[, c("ï..DIRECTORIO","SECUENCIA_P","ORDEN", "P6435")]

# Salud

Salud<- read.table("Salud.csv", sep = ";", header = T)
Salud<-Salud[,c("ï..DIRECTORIO","SECUENCIA_P","ORDEN","P6090","P6127")]

# Servicios del hogar

ServiciosDelHogar<- read.table("Servicios del hogar.csv", sep = ";", dec=",", header = T)
ServiciosDelHogar<-ServiciosDelHogar[,c("ï..DIRECTORIO","SECUENCIA_ENCUESTA","ORDEN","P5000","P5666","P5305", "I_HOGAR")]

# Tecnología e información y comunicación

tecn_inf_comunicacion <- read.table("Tecnologías de información y comunicación.csv", sep=";", header = T) 
tecn_inf_comunicacion <- tecn_inf_comunicacion[, c("ï..DIRECTORIO","SECUENCIA_P","ORDEN","P769")]

# Tenencia y financiación de la vivienda que ocupa el hogar

financiacion_vivienda <- read.table("Tenencia y financiación de la vivienda que ocupa el hogar.csv", sep=";", header = T)
financiacion_vivienda <- financiacion_vivienda[,c("ï..DIRECTORIO","SECUENCIA_ENCUESTA","ORDEN","P5095")]

# Uso de energéticos del hogar

energeticos_hogar <- read.table("Uso de energéticos del hogar.csv", sep=";", header = T)
energeticos_hogar <- energeticos_hogar[,c("ï..DIRECTORIO","SECUENCIA_ENCUESTA","ORDEN", "P5018", "P5018S1")]

Unión de las bases de datos:

Se creó una única base de datos con la variable de interés (Número de hijos) y las demás variables seleccionadas. Dado que las posibles variables explicativas provenían de diferentes tablas, se procedió a realizar un merge entre ellas, usando como variable de referencia la columna “Directorio” y “Secuencia” que son las dos variables que identifican a un hogar, y teniendo especial cuidado en la unión de tablas donde las preguntas pueden ser por vivienda, hogar o integrantes y se debía llevar a una misma estructura de hogares.

# Merge de la base de datos de caracteristicas del hogar con condiciones de vida

# SECUENCIA_P Y SECUENCIA_ENCUESTA son las mismas variables pero toman un nombre distinto en ambas bases de datos.
Base1 <- merge(Caracteristicas_hogar_personas, condiciones_de_vida, by.x = c("ï..DIRECTORIO","SECUENCIA_P"), by.y = c("ï..DIRECTORIO","SECUENCIA_ENCUESTA"), all.x =TRUE)

# Merge de Base1 con datos vivienda

# Se realiza el merge solo por "ï..DIRECTORIO" ya que es el identificador de la vivienda y no del hogar, por lo tanto varios hogares de una misma vivienda recibiran la misma información sobre las variables de Datos_vivienda.
Base2 <- merge(Base1, Datos_vivienda, by="ï..DIRECTORIO", all.x=T)

# Merge de Base2 con educación

# el merge se realiza con tres identificadores debido a que se selecciona la información del hogar solo por el jefe de la misma respecto a la educación.
Base3 <- merge(Base2, Educacion, by =c("ï..DIRECTORIO","SECUENCIA_P", "ORDEN"), all.x=TRUE)

# Merge de todas las bases de datos restantes

## Bases de personas 
#(por cada integrante del hogar) 
#(el merge sirve para obtener un solo registro por hogar)

Base4 <- Reduce(function(...) merge (..., by=c("ï..DIRECTORIO","SECUENCIA_P", "ORDEN"), all=T), list(Base3, fuerza_trabajo, Salud, tecn_inf_comunicacion))
Base4[,c("ORDEN")] <- NULL

## Bases de hogares 
#(información general del hogar)

Base5 <- Reduce(function(...) merge (..., by= c("ï..DIRECTORIO","SECUENCIA_ENCUESTA", "ORDEN"), all=T), list(ServiciosDelHogar, financiacion_vivienda, energeticos_hogar))
Base5[,c("ORDEN")] <- NULL

Una vez obtenida la base 4 agrupada por i..DIRECTORIO y SECUENCIA_P y la base 5 agrupada por i..DIRECTORIO y SECUENCIA_ENCUESTA, se procede a agruparlas igualando SECUENCIA_P con SECUENCIA_ENCUESTA.

Base6 <- merge(Base4, Base5, by.x =c("ï..DIRECTORIO","SECUENCIA_P"),
               by.y =c("ï..DIRECTORIO","SECUENCIA_ENCUESTA"), all=TRUE)

Finalmente, se agrupa la base anterior con la base que contiene el número de hijos, obteniendo:

# Base final

Base_final <- merge(Base6, num_hijos_final, by =c("ï..DIRECTORIO","SECUENCIA_P"), all.x=TRUE)
Base_final[,c("P6435","P6051","P5018S1","ï..DIRECTORIO","SECUENCIA_P")] <- NULL
P6020 P6040 P5502 P756 P6081 P6087 P6083 P6088 P6080 P784S4A3 CANT_HOGARES_VIVIENDA P1070 P4015 P8520S1 P8520S1A1 P8520S5 P8520S3 P8520S4A1 P8587 P8586 P6090 P6127 P769 P5000 P5666 P5305 I_HOGAR P5095 P5018 P5018S Num Integrantes Num Hijos
2 44 2 1 2 10 3 1 6 0 1 2 4 1 3 1 1 3 7 2 1 3 1 3 1 2 3800000.0 3 85000 85000 4 1
1 61 6 1 3 2 3 2 5 0 1 1 4 1 2 1 1 3 5 2 1 2 1 5 1 1 3656652.8 4 62000 62000 10 7
1 79 6 2 3 10 3 10 6 0 1 1 4 1 3 1 1 3 11 2 1 4 2 5 1 1 4200000.0 1 189000 189000 2 0
2 37 5 2 3 2 2 3 6 0 1 2 4 1 3 1 1 3 9 2 1 2 2 3 1 2 1365000.0 3 188800 188800 3 0
1 72 5 1 3 3 3 2 5 0 1 2 4 1 2 1 1 3 4 2 1 3 NA 4 1 2 765833.3 1 87000 87000 3 0
1 73 5 2 3 9 3 9 6 0 1 2 6 1 2 1 1 3 3 2 1 2 1 3 2 2 1785721.9 3 30000 30000 1 0

Medidas de localización y escala

Se realiza un análisis descriptivo a cada variable donde se identifica el rango y media de las variables continuas y discretas respectivamente, y la proporción de cada clase en las variables categóricas, además de la identificación de las variables con valores faltantes.

require(knitr)
require(kableExtra)
kable(summary(Base_final), align = "c")%>%
  kable_paper("striped")%>%
  scroll_box(width = "100%", height = "300px")
Genero Edad Estado_civil Lugar_nacimiento Vive_hogar_padre Educacion_padre Vive_hogar_madre Educacion_madre Etnia Num_Subsidios Cant_hogares_vivienda Tipo_vivienda Material_pisos Energia_electrica Estrato Acueducto Alcantarillado Basuras_semana Nivel_educativo Estudia Afiliado Salud_general Uso_celular Num_cuartos Gas_natural Telefonia_fija Ingresos_hogar Contrato_vivienda Ultimo_pago_energia Pago_mes_energia Num_integrantes Num_hijos
1:59884 Min. : 13.00 1: 2317 1:52361 1: 674 1 :28980 1: 2181 1 :30002 1: 8875 Min. :0.00000 Min. :1.000 1:71614 1: 116 1:88799 1 :45059 1:67015 1:47003 Min. :1.00 3 :36758 1: 2366 1:88203 1: 7244 1 :65611 Min. : 1.000 1:36825 1: 9145 Min. : 0 1:41945 Min. : 0 Min. : 333.3 Min. : 1.000 Min. : 0.000
2:34109 1st Qu.: 36.00 2:33748 2:39265 2:46104 9 :21622 2:55601 9 :21970 2: 38 1st Qu.:0.00000 1st Qu.:1.000 2:17847 2: 791 2: 5194 2 :23622 2:26978 2:46990 1st Qu.:2.00 5 :18848 2:91627 2: 5555 2:63360 2 :16942 1st Qu.: 2.000 2:57168 2:84848 1st Qu.: 530000 2: 2401 1st Qu.: 15000 1st Qu.: 20000.0 1st Qu.: 2.000 1st Qu.: 0.000
NA Median : 48.00 3: 7963 3: 2367 3:47215 10 :19631 3:36211 10 :14782 3: 309 Median :0.00000 Median :1.000 3: 2576 3: 158 NA 3 : 7961 NA NA Median :3.00 4 :12350 NA 9: 235 3:22051 3 : 1863 Median : 3.000 NA NA Median : 1020000 3:23108 Median : 30000 Median : 35000.0 Median : 3.000 Median : 1.000
NA Mean : 48.86 4:16077 NA NA 2 :12680 NA 2 :13906 4: 54 Mean :0.01813 Mean :1.022 4: 1860 4:38695 NA 0 : 3999 NA NA Mean :2.47 1 : 8603 NA NA 4: 1338 4 : 380 Mean : 3.084 NA NA Mean : 1727919 4:19324 Mean : 46910 Mean : 51487.1 Mean : 3.081 Mean : 1.302
NA 3rd Qu.: 61.00 5:12082 NA NA 4 : 4682 NA 4 : 5207 5: 9168 3rd Qu.:0.00000 3rd Qu.:1.000 5: 96 5: 6957 NA 4 : 2421 NA NA 3rd Qu.:3.00 11 : 5536 NA NA NA NA’s: 9197 3rd Qu.: 4.000 NA NA 3rd Qu.: 1873116 5: 3569 3rd Qu.: 57000 3rd Qu.: 60000.0 3rd Qu.: 4.000 3rd Qu.: 2.000
NA Max. :106.00 6:21806 NA NA (Other): 5724 NA (Other): 5945 6:75549 Max. :9.00000 Max. :5.000 NA 6:37107 NA (Other): 5737 NA NA Max. :9.00 (Other): 9532 NA NA NA NA Max. :16.000 NA NA Max. :284600000 6: 3646 Max. :1000000 Max. :1000000.0 Max. :19.000 Max. :14.000
NA NA NA NA NA NA’s : 674 NA NA’s : 2181 NA NA NA NA 7:10169 NA NA’s : 5194 NA NA NA’s :34262 NA’s : 2366 NA NA NA NA NA NA NA NA NA NA’s :5194 NA’s :17719 NA NA

Se decidió remover de la base de datos a aquellas variables cuyos valores faltantes superar un tercio de la cantidad de registros en la base de datos.

Gráficos descriptivos

Con el fin de depurar la base de datos, mediante gráficos se realizó un análisis descriptivo de las variables.

Para finalizar la etapa de preprocesamiento, se crearon gráficos Boxplots del Número de hijos vs las variables categóricas, respectivamente, con el fin de analizar la posible influencia o relación de cada predictora con la respuesta.

sapply(1:32, function(i){
  boxplot(Base_final$Num_hijos~Base_final[, i], xlab = nombres[i])
})
gra1

gra2

gra3

gra4

gra5

gra6

gra7

gra8

gra9

gra10

gra11

gra12

gra13

gra14

gra15

gra16

gra17

gra18

gra19

gra20

gra21

gra22

gra23

gra24

gra25

gra26

gra27

Y para las variables numéricas se utilizan gráficos de puntos vs Num_hijos para analizar la posible influencia o relación de cada predictora con la respuesta.

puntos1

puntos2

puntos3

puntos4

Variables escogidas a partir de los graficos descriptivos

Variables interesantes
Genero
Edad
Num_integrantes
Num_cuartos
Estrato
Tipo_vivienda
Num_Subsidios
Educacion_madre
Estado_civil
Ultimo_pago_energia
Ingresos_hogar
Cant_hogares_vivienda
Num_hijos

Se realiza un subset con las variables interesantes

Genero Edad Num_integrantes Num_cuartos Estrato Tipo_vivienda Num_Subsidios Educacion_madre Estado_civil Ultimo_pago_energia Ingresos_hogar Cant_hogares_vivienda Num_hijos
2 44 4 3 3 2 0 1 2 85000 3800000.0 1 1
1 61 10 5 2 1 0 2 6 62000 3656652.8 1 7
1 79 2 5 3 1 0 10 6 189000 4200000.0 1 0
2 37 3 3 3 2 0 3 5 188800 1365000.0 1 0
1 72 3 4 2 2 0 2 5 87000 765833.3 1 0
1 73 1 3 2 2 0 9 5 30000 1785721.9 1 0

Las variables categóricas de Base_interesante se convierten a factor y se crea un modelo de regresión lineal múltiple para poder utilizar selección de variables por regresión paso a paso.

Regresión por paso a paso

require(olsrr)

mod1 <- lm(Num_hijos~., data = Base_interesante) # Modelo de regresión lineal múltiple
ols_step_both_p(mod1) # Selección
## 
##                                       Stepwise Selection Summary                                       
## ------------------------------------------------------------------------------------------------------
##                                 Added/                   Adj.                                             
## Step         Variable          Removed     R-Square    R-Square       C(p)           AIC         RMSE     
## ------------------------------------------------------------------------------------------------------
##    1      Num_integrantes      addition       0.836       0.836    14121.0890    147987.0388    0.5567    
##    2        Num_cuartos        addition       0.838       0.838    12584.9020    146651.7229    0.5525    
##    3          Estrato          addition       0.838       0.838    12431.6950    146517.6593    0.5521    
##    4       Tipo_vivienda       addition       0.839       0.839    12302.1070    146404.1379    0.5517    
##    5       Estado_civil        addition       0.839       0.839    12229.5050    146340.5776    0.5515    
##    6          Genero           addition       0.859       0.859        2.3500    131676.5283    0.5171    
##    7    Ultimo_pago_energia    addition       0.859       0.859      -10.3360    131663.8376    0.5170    
## ------------------------------------------------------------------------------------------------------

Selección de las variables de interés con Lasso

Se toma la Base_final que posee 32 variables y se convierten las variables categóricas a factor. Se eliminan las variables con mayor número de NA y se eliminan las filas con NA, para poder aplicar Lasso.

Se crea una matriz de diseño para aplicar Regresión Lasso

x <- model.matrix(Num_hijos ~ ., Base_menos_Nas)[,-1] # Matriz de diseño
y <- Base_menos_Nas$Num_hijos # Variable respuesta

# Aplicación de la técnica de regularización

require(glmnet)

gridz <- 10^seq(-2,10, length = 100) # Malla de lambdas
lasso.mod <- glmnet(x, y, alpha = 1, lambda = gridz) # Ajuste del modelo

Se hace validación cruzada para seleccionar el \(\lambda\) óptimo, que se aplicará en el modelo

set.seed(23)

# Indices para las filas del conjunto de entrenamiento
train <- sample(1:nrow(x), nrow(x)/2)

# Indices para las filas del conjunto de test
test <- -train
y.test <- y[test]

# Validación cruzada
cv.out <- cv.glmnet(x[train,], y[train], alpha=1)

# Obtención del mejor lambda
bestlam <-cv.out$lambda.min

# Lasso con el lambda óptimo
out <- glmnet(x, y, alpha=1)
lasso.coef <-predict(out, type = "coefficients", s=bestlam)[1:90, ]

A continuación se muestra las variables seleccionadas por medio de los dos métodos anteriores:

Variables Regresion por pasos Lasso
Genero X X
Edad
Estado_civil X X
Lugar_nacimiento X
Vive_hogar_padre
Educacion_padre
Vive_hogar_madre X
Educacion_madre
Etnia X
Num_subsidios X
Cant_hogares_vivienda
Tipo_vivienda X X
Material_pisos X
Energia_electrica
Estrato X
Acueducto
Alcantarillado
Nivel_educativo X
Estudia
Afiliado X
Salud_general
Uso_celular X
Num_cuartos X X
Gas_natural
Telefonia_fija
Ingresos_hogar
Contrato_vivienda X
Ultimo_pago_energia X
Num_integrantes X

Con los anteriores procesos, se obtiene la siguiente base, que se usará en la parte de modelamiento

Genero Edad Num_integrantes Num_cuartos Estrato Tipo_vivienda Num_Subsidios Educacion_madre Estado_civil Ultimo_pago_energia Ingresos_hogar Cant_hogares_vivienda Num_hijos Uso_celular Vive_hogar_madre Contrato_vivienda Etnia Afiliado Lugar_nacimiento Nivel_educativo
2 44 4 3 3 2 0 1 2 85000 3800000.0 1 1 1 3 3 6 1 1 7
1 61 10 5 2 1 0 2 6 62000 3656652.8 1 7 1 3 4 5 1 1 5
1 79 2 5 3 1 0 10 6 189000 4200000.0 1 0 2 3 1 6 1 2 11
2 37 3 3 3 2 0 3 5 188800 1365000.0 1 0 2 2 3 6 1 2 9
1 72 3 4 2 2 0 2 5 87000 765833.3 1 0 NA 3 1 5 1 1 4
1 73 1 3 2 2 0 9 5 30000 1785721.9 1 0 1 3 3 6 1 2 3

Modelamiento

La mayoría de las variables escogidas como significativas corresponden a variables categóricas, se seleccionaron modelos que permiten el correcto manejo de las mismas. A continuación se ilustra la etapa de modelamiento:

Se realiza un gráfico de barras, para observar como se distribuye el número de hijos en los hogares colombianos.

barplot(prop.table(table(Base_modelar$Num_hijos)),
        main = "Proporción del número de hijos",
        xlab = "Número de hijos",
        col = "cyan4")
grid()

Se deduce que la mayoría de las familias tienen entre 0 y 2 hijos, sin embargo, hay una proporción considerable de hogares que poseen 3, 4 y 5 hijos. Pero, a partir de los 6 hijos la proporción decae, por lo que se podría pensar en agrupar a los hogares en 5 categorías comprendidas como: 0, 1, 2, 3, 4, 5+.

Además, que en una situación real resulta poco relevante determinar con precisión el número de hijos cuando estos son muchos, ya que con la información de que es una cantidad numerosa de hijos es suficiente para tomar la decisión que se requiera.

Base_de_ensayo <- Base_modelar

# Se agrupa los hogares con 5 hijos o más en una sola categoría
Base_de_ensayo$Num_hijos[Base_de_ensayo$Num_hijos >= 5] <- 5
Número de hijos Frecuencia
0 34418
1 23838
2 19896
3 9370
4 3770
5 o más 2701

Bosques Aleatorios para selección de variables

Se organiza la base de datos para aplicar el modelo

library(tidyverse)

# Se omiten las filas que poseen NA
Base_modelar_f <- na.omit(Base_de_ensayo)

# Se convierte la variable Num_hijos a factor
Base_modelar_f$Num_hijos <- as.factor(Base_modelar_f$Num_hijos) 

set.seed(15234) # Semilla

# Se saca una muestra de entrenamiento que conserve las proporciones en la variable Num_hijos
trn_prop <- Base_modelar_f %>%
  mutate(
    var_indx = 1:dim(Base_modelar_f)[1]
  ) %>% 
  group_by(Num_hijos) %>% 
  sample_frac(0.8, replace = F)

# Se saca la muestra de test con las que no fueron seleccionadas en la muestra de train
tst_prop <- Base_modelar_f[-trn_prop$var_indx, ]

# Se elimina la variable de indice
trn_prop$var_indx <- NULL

Con la función ranger aplicamos el modelo de Bosques aleatorios

# Modelo RF
mod_RF <- ranger(
  Num_hijos~., 
  data = (trn_prop), 
  num.trees = 500, 
  mtry = 5, 
  max.depth = 8,
  importance = 'impurity'
)

En la siguiente gráfica se muestra las variables que tienen mayor importancia para Bosques aleatorios:

Se utiliza los pesos de importancia asignados por Bosques Aleatorios para escoger las variables que se utilizarán en el resto de modelos, además se tiene en cuenta la cantidad de NA en cada una de las variables.

kable(colSums(is.na(Base_de_ensayo)), align = "c", col.names = "Cantidad de NA") %>%
  kable_paper("striped", full_width =F)
Cantidad de NA
Genero 0
Edad 0
Num_integrantes 0
Num_cuartos 0
Estrato 5194
Tipo_vivienda 0
Num_Subsidios 0
Educacion_madre 2181
Estado_civil 0
Ultimo_pago_energia 5194
Ingresos_hogar 0
Cant_hogares_vivienda 0
Num_hijos 0
Uso_celular 9197
Vive_hogar_madre 0
Contrato_vivienda 0
Etnia 0
Afiliado 0
Lugar_nacimiento 0
Nivel_educativo 2366

Aunque Ingresos_hogar, Nivel_educativo, Uso_celular, Ultimo_pago_energia, Educacion_madre y Estrato en primera instancia tienen una importancia elevada para el modelo se decide eliminarlas ya que contienen una gran cantidad de datos faltantes.

Dado que el anterior modelo fue ajustado eliminando todas las filas con NAs, se procedió a eliminar una a una según el orden de importancia las columnas con NAs y a verificar su impacto en la tasa de acierto en el conjunto de validación.

El resultado que se obtuvo fue que la tasa de acierto levemente aumentó a medida que se excluyeron las columnas con NAs y por ende no se eliminaba ninguna fila del conjunto de entrenamiento.

Por último, en busca de un modelo parsimonioso se ajustó excluyendo una a una las variables restantes (sin NAs) según el orden de importancia en el modelo Random Forest; Donde se tuvo en cuenta que el orden de importancia no se viera dramáticamente afectado de modelo a modelo y que la tasa de acierto no disminuyera drásticamente.

Del resultado anterior se determinó conservar las siguientes 5 variables.

Variables escogidas

Las variables a utilizar en los modelos son las escogidas en orden de importancia por Bosques Aleatorios, se muestran a continuación:

  • Num_integrantes
  • Estado_civil
  • Genero
  • Edad
  • Vive_hogar_madre
  • Num_hijos
library(tidyverse)

# Variables en orden de importancia según RF
var_imprt <-  c(
    "Num_integrantes",
    "Estado_civil",
    "Genero",
    "Edad",
    "Vive_hogar_madre",
    "Num_hijos"
  )


# Conjunto de datos con las variables importantes
Base_modelar_f <- Base_de_ensayo[,var_imprt]

# Se convierte la variable Num_hijos a factor
Base_modelar_f$Num_hijos <- as.factor(Base_modelar_f$Num_hijos) 

set.seed(15234) # Semilla

# Se saca una muestra de entrenamiento que conserve las proporciones en la variable Num_hijos
trn_prop <- Base_modelar_f %>%
  mutate(
    var_indx = 1:dim(Base_modelar_f)[1]
  ) %>% 
  group_by(Num_hijos) %>% 
  sample_frac(0.8, replace = F)

# Se saca la muestra de test con las que no fueron seleccionadas en la muestra de train
tst_prop <- Base_modelar_f[-trn_prop$var_indx, ]

# Se elimina la variable de indice
trn_prop$var_indx <- NULL

Modelo de Regresión Lineal Múltiple

Se debe convertir la variable respuesta nuevamente a numérica para poder aplicar regresión lineal.

modelo1 <- lm(as.numeric(as.character(Num_hijos))~., data=trn_prop)

El error estándar del modelo es 0.5346394

Análisis de residuales.

Se puede apreciar que no se cumple el supuesto de normalidad en los residuales, homocedasticidad e independencia, por lo tanto no es adecuado para realizar predicciones.

Matriz de confusión

Predicciones
Reales
0 1 2 3 4 5
-1 122 0 0 0 0 0
0 5948 122 0 0 0 0
1 646 4143 321 0 0 0
2 127 409 3379 758 1 0
3 32 83 249 1056 578 4
4 7 7 19 50 143 215
5 1 3 7 8 26 200
6 0 1 3 1 4 67
7 0 0 0 0 0 25
8 0 0 1 1 2 21
9 0 0 0 0 0 4
10 1 0 0 0 0 0
11 0 0 0 0 0 1
12 0 0 0 0 0 2
13 0 0 0 0 0 1

La tasa de acierto es 0.1125592 y la tasa de error es 0.8874408

Árbol de clasificación

Con la función rpart se ajusta el modelo y se analizan los resultados

mod1_arboles <- rpart(Num_hijos~., data = trn_prop)

Se observa que la variable Num_integrantes es una de las más importantes, en la creación del árbol de clasificación.

Se hacen las predicciones y se obtiene la siguiente matriz de confusión

Predicciones
Reales
0 1 2 3 4 5
0 6188 333 0 0 0 0
1 410 3795 148 0 0 0
2 176 483 3287 60 0 0
3 91 122 444 1583 163 0
4 13 28 73 182 458 54
5 6 7 27 49 133 486

La tasa de acierto es 0.8403107 y la tasa de error es 0.1596893

Árboles de Regresión

mod1_reg_arboles <- rpart(as.numeric(as.character(Num_hijos))~., data = trn_prop)

Se observa que en la construcción del árbol de regresión solo se utilizaron dos variables, Num_integrantes y Estado_civil.

Se hacen las predicciones y se obtiene la matriz de confusión

Predicciones
Reales
0 1 2 3 4 5
0 6407 1425 0 0 0 0
1 285 2756 317 0 0 0
2 140 483 3264 455 0 0
3 33 69 298 1188 163 0
4 19 35 100 231 591 540

La tasa de acierto es 0.7556785 y la tasa de error es 0.2443215

Regresión Poisson

Se ajusta el modelo usando la función gamlss del paquete gamlss, con una familia Poisson.

HijosPoisson <-gamlss(as.numeric(as.character(Num_hijos))~., data= trn_prop, family=PO(mu.link="log"))
## GAMLSS-RS iteration 1: Global Deviance = 170257.6 
## GAMLSS-RS iteration 2: Global Deviance = 170257.6

Se hacen las predicciones y obtenemos la matriz de confusión

Predicciones
Reales
0 1 2 3 4 5
-2 62 0 0 0 0 0
-1 4464 365 27 1 0 0
0 2326 4272 3270 333 19 0
1 30 126 670 1525 696 221
2 1 5 11 13 36 268
3 0 0 1 2 3 43
4 1 0 0 0 0 4
5 0 0 0 0 0 4
acierto<-sum(diag(MC3))/sum(MC3)
error <- 1-acierto

La tasa de acierto es 0.2819831, la tasa de error es 0.7180169, por otro lado se observan predicciones fuera del rango de la variable respuesta, esto puede suceder si no se cumplen los supuestos del modelo.

Bosque Aleatorio

Se ajusta un Bosque Aleatorio con la función ranger

mod_RF <- ranger(
  Num_hijos~., 
  data = (trn_prop), 
  num.trees = 500, # número de árboles
  mtry = 5, # numero de variables a utilizar en cada árbol
  max.depth = 8, # profundidad de cada árbol
  importance = 'impurity'
)

Se hacen las predicciones y se obtiene la matriz de confusión

Predicciones
Reales
0 1 2 3 4 5
0 6254 207 9 0 0 0
1 426 3996 145 1 0 0
2 127 428 3336 77 1 1
3 58 90 385 1512 42 1
4 13 35 72 223 539 9
5 6 12 32 61 172 529

La tasa de acierto es 0.8599394 y la tasa de error es 0.1400606

Naive Bayes

Se ajusta un clasficador por el método de Bayes ingenuo

mod_Naive_Bayes <- naiveBayes(Num_hijos ~ ., data = trn_prop)

Se hacen las predicciones y se obtiene la matriz de confusión

Predicciones
Reales
0 1 2 3 4 5
0 5909 1342 35 0 0 0
1 830 3003 999 29 0 0
2 96 319 2547 426 0 0
3 38 80 332 1258 364 10
4 9 18 52 143 335 193
5 2 6 14 18 55 337

La tasa de acierto es 0.7122187 y la tasa de error es 0.2877813

Knn

Antes de aplicar el modelo se deben organizar las variables, como se muestra a continuación.

Conversión de las variables categoricas a variables dummy

library(dummies)

# Conjunto de entrenamiento
Base_KNN_dummy_trn <- dummy.data.frame(data=data.frame(trn_prop[ ,-6]))
Base_KNN_dummy_trn <- cbind(Base_KNN_dummy_trn,"Num_hijos" = trn_prop$Num_hijos)

# Conjunto de prueba
Base_KNN_dummy_tst <- dummy.data.frame(data=tst_prop[ ,-6])
Base_KNN_dummy_tst <- cbind(Base_KNN_dummy_tst,"Num_hijos" = tst_prop$Num_hijos)

Se normalizan las Variables Numéricas

#Conjunto de entrenamiento
datos_c_trn <- Base_KNN_dummy_trn
datos_c_trn[,c(1,10)] <- scale(datos_c_trn[,c(1,10)]) # normalización

#Conjunto de prueba
datos_c_tst <- Base_KNN_dummy_tst
datos_c_tst[,c(1,10)] <- scale(datos_c_tst[,c(1,10)])

Conjuntos de entrenamiento y test

train <- datos_c_trn[ ,-14] # crea train sin la variable respuesta
test <- datos_c_tst[ ,-14] # crea test sin la variable respuesta

y_train <- datos_c_trn[ ,14]
y_test <- datos_c_tst[ ,14]

Con el fin de elegir un K apropiado se entrena el modelo variando el K entre 1 y 30, después se escoge el que mejor se ajusta al conjunto de entrenamiento.

modelo <- train.kknn(Num_hijos ~ ., data = datos_c_trn, kmax = 30)

Con el k óptimo que es igual a 18 se ajusta el modelo knn, se hacen las predicciones y se obtiene la matriz de confusión

knn_model <- knn(train, test, cl = y_train, k = 18)
Predicciones
Reales
0 1 2 3 4 5
0 6285 221 21 7 2 0
1 442 3984 152 1 0 0
2 107 434 3346 97 3 0
3 40 91 369 1517 78 2
4 7 30 68 207 535 43
5 3 8 23 45 136 495

La tasa de acierto es 0.8597266 y la tasa de error es 0.1402734.


Conclusión del ajuste de modelos

Los modelos escogidos son de regresión y clasificación, en cada uno se adaptó la variable respuesta. En los de clasificación se obtienen las predicciones como el número de hijos puntual, en los de regresión se obtienen aproximaciones decimales las cuales previamente debían ser redondeadas para ser comparadas con los valores reales, en general por este último procedimiento se podía notar que funcionaban mucho mejor en los modelos de clasificación (su tasa de aciertos era la más alta) por lo tanto finalmente estos fueron considerados como los favoritos y continuaron en el proceso de selección de modelos, además, cabe aclarar que a cada modelo le fue ingresado las variables como se debía según su proceso de ajuste, por ejemplo, en el modelo de Knn las variables explicativas fueron ingresadas, estandarizadas las que son numéricas y se crearon variables dummy para las categóricas, en general el desempeño de este modelo fue muy bueno, pero su tiempo de ejecución fue superior al de los otros; este es uno de los criterios utilizados en la selección.

Resultados

Selección del mejor modelo

Para comparar la eficiencia de los modelos se crea una matriz en la cual se almacenará las tasas de acierto de los modelos que se construyeron en el paso anterior

df <- matrix(rep(NA,80), nrow=20, ncol=4)
df <- data.frame(df)
colnames(df) <- c("Arbol_clasificacion","RandomForest", "NaiveBayes", "Knn")

Para llenar la matriz anterior se realiza un for que ejecuta cada uno de los modelos 20 veces, escogiendo aleatoriamente el conjunto de entrenamiento y el conjunto de prueba

for(i in 1:20){

  set.seed(i) # Semilla
  
  # Se saca una muestra de entrenamiento que conserve las proporciones en la varaible Num_hijos
  
  trn_prop <- Base_modelar_f %>%
    mutate(
      var_indx = 1:dim(Base_modelar_f)[1]
    ) %>% 
    group_by(Num_hijos) %>% 
    sample_frac(0.8, replace = F)
  
  # Se saca la muestra de test con las que no fueron seleccionadas en la muestra de
  # train
  tst_prop <- Base_modelar_f[-trn_prop$var_indx, ]
  
  # Se elimina la variable de índice
  trn_prop$var_indx <- NULL
  
  trn_prop <- trn_prop[sample(1:dim(trn_prop)[1]), ]
  tst_prop <- tst_prop[sample(1:dim(tst_prop)[1]), ]
  
    # Ajuste de los modelos
  
  ## Árbol de clasificación 
  arbol_clasificacion <- rpart(Num_hijos~., data = trn_prop)
  pred_arbol_clasificacion <-  predict(arbol_clasificacion, newdata = tst_prop, type=
                                         "class")
  
  tasa_arbol_clasificacion <- matriz_confusion(pred_arbol_clasificacion,
                                               tst_prop$Num_hijos)
  
  # Modelo RF
  RF <- ranger(Num_hijos~.,  data = (trn_prop),   num.trees = 100,  mtry = 5, 
               max.depth = 8,  importance = 'impurity')
  
  
  pred_RF <- predict(RF, data = (tst_prop))
  
  tasa_RF <- matriz_confusion(pred_RF$predictions, tst_prop$Num_hijos)
  
  ## Naive Bayes
  
  Naive_Bayes <- naiveBayes(Num_hijos ~ ., data = trn_prop)
  pred_Naive_Bayes <- predict(Naive_Bayes, newdata = tst_prop, type="class")
  
  tasa_Naive_Bayes <- matriz_confusion(pred_Naive_Bayes, tst_prop$Num_hijos)
  
  
  ## Knn
  
  # Conjunto de entrenamiento
  Base_KNN_dummy_trn <- dummy.data.frame(data=data.frame(trn_prop[ ,-6]))
  Base_KNN_dummy_trn <- cbind(Base_KNN_dummy_trn,"Num_hijos" = trn_prop$Num_hijos)
  # Conjunto de prueba
  Base_KNN_dummy_tst <- dummy.data.frame(data=tst_prop[ ,-6])
  Base_KNN_dummy_tst <- cbind(Base_KNN_dummy_tst,"Num_hijos" = tst_prop$Num_hijos)
  
  #Conjunto de entrenamiento
  datos_c_trn <- Base_KNN_dummy_trn
  datos_c_trn[,c(1,10)] <- scale(datos_c_trn[,c(1,10)])
  
  #Conjunto de prueba
  datos_c_tst <- Base_KNN_dummy_tst
  datos_c_tst[,c(1,10)] <- scale(datos_c_tst[,c(1,10)])
  
  # Separación de la variable respuesta
  train <- datos_c_trn[ ,-14] # crea train sin la variable respuesta
  test <- datos_c_tst[ ,-14] # crea test sin la variable respuesta
  y_train <- datos_c_trn[ ,14]
  y_test <- datos_c_tst[ ,14]
  pred_knn <- knn(train, test, cl = y_train, k = 20)
  
  tasa_knn <- matriz_confusion(pred_knn, y_test)
  
  tasas <- c(tasa_arbol_clasificacion, tasa_RF, tasa_Naive_Bayes, tasa_knn)
  
  df[i,] <- tasas
  
}
Arbol_clasificacion RandomForest NaiveBayes Knn
1 0.84280 0.86150 0.715600 0.861000
2 0.84260 0.86240 0.717300 0.860900
3 0.83990 0.85970 0.719800 0.856900
4 0.83690 0.85800 0.708100 0.858200
5 0.84250 0.86500 0.713500 0.864400
6 0.84180 0.86360 0.721000 0.860600
7 0.84110 0.86040 0.717700 0.858600
8 0.84170 0.86240 0.709900 0.858700
9 0.84210 0.86350 0.713700 0.861900
10 0.83940 0.86310 0.715300 0.861100
11 0.84730 0.86760 0.717200 0.863900
12 0.84220 0.86220 0.722300 0.860700
13 0.84320 0.86410 0.721600 0.862600
14 0.84350 0.86670 0.709800 0.867500
15 0.83990 0.86030 0.713800 0.857200
16 0.83970 0.86330 0.708600 0.860800
17 0.83980 0.86160 0.712200 0.858500
18 0.84220 0.86060 0.715300 0.859200
19 0.84140 0.86140 0.710000 0.860500
20 0.84160 0.86040 0.708800 0.860700
Media 0.84158 0.86239 0.714575 0.860695

Bosques aleatorios se escogió ya que presenta una de las tasas de acierto más altas entre todos los modelos desarrollados, el tiempo de predicción es bastante rápido, y permite reducir la dimensionalidad del conjunto de datos, ya que este valora y utiliza 5 variables tanto para la modelación, como para la predicción, además de que estas variables no tienen valores faltantes permitiendo contar con el conjunto de datos completo que 93993 registros.

Como último filtro, buscando una experiencia más veloz para los usuarios de la app se decide reducir el número de árboles usados en el proceso anterior. Para esto se hace una prueba cambiando el tamaño del bosque a 100 árboles en lugar de 500

RF <- ranger(Num_hijos~.,  data = (trn_prop),   num.trees = 100,  mtry = 5, 
             max.depth = 8,  importance = 'impurity')
pred_RF <- predict(RF, data = (tst_prop))
tasa_RF <- matriz_confusion(pred_RF$predictions, tst_prop$Num_hijos)

La tasa de acierto tanto con 100 y 500 árboles es de aproximadamente 0.86, es decir, el tamaño del bosque no representa un cambio significativo a la hora de predecir pero si en tiempo de ejecución, por lo que se decide implementar el modelo con 100 árboles.

Ajuste del modelo final con todas las observaciones

Con el fin de presentar el modelo al público se hace uso de todos los registros para su entrenamiento.

RandomForest <- ranger(Num_hijos~.,  data = Base_modelo,   num.trees = 100,  mtry = 5, 
             max.depth = 8,  importance = 'impurity')

Prueba de Escritorio

A continuación, se probarán de forma rápida las predicciones del modelo final usando como variables de entrada la información de los hogares de cada uno de los investigadores y contrastándola con el número de hijos real de cada hogar.

require(ranger)
# datos de los investigadores
# Nombre <- c(Num_integrantes, Estado_civil, Genero, Edad, Vive_hogar_madre)
Miguel <- c(3, 6, 1, 52, 2)
Jennifer <- c(4, 2, 2, 43, 3)
Juan <- c(4, 6, 1, 59, 2)
Cristina <- c(3, 2, 2, 50, 2)
Salome <- c(3, 4, 2, 53, 3)

# Poniendo los datos en un data.frame para realizar predicciones
df <- rbind(Miguel, Jennifer, Juan, Cristina, Salome) #Unión de los datos
df <- data.frame(df) #Conversión a data.frame

# Nombres de las variables
colnames(df) <- c("Num_integrantes",  
                  "Estado_civil", 
                  "Genero", 
                  "Edad",
                  "Vive_hogar_madre")


prediccion <- predict(RandomForest, df) # Predicción con el Random Forest
prediccion$predictions # Imprime las predicciones
## [1] 1 2 2 1 2
## Levels: 0 1 2 3 4 5
Inverstigador Valores_predichos Valores_Reales
Miguel 1 1
Jennifer 2 2
Juan 2 2
Cristina 1 1
Salome 2 2

Nótese que el modelo final predijo sin error el número de hijos en el hogar de cada uno de los investigadores.

Conclusiones

  • En el mundo estadístico los Bosques Aleatorios son considerados por algunos como la panacea para los problemas de clasificación, en este problema se ve que este tipo de modelos es el que presenta mejores resultados, además, es un modelo parsimonioso, que se puede llevar a la práctica y presenta buenos resultados.

  • Dado que los resultados con los métodos de Random forest fueron muy buenos se recomienda para futuros estudios ensayar modelo tipo boosting.

  • La predicción del número de hijos tiene bastantes utilidades en diferentes sectores por ejemplo en el caso de una inmobiliaria, que quiere arrendar una nueva propiedad y dejarla en manos de la familia ideal. La inmobiliaria no quiere invadir e incomodar la privacidad de sus clientes; pero con poca información y con ayuda de esta aplicación la inmobiliaria podrá saber cuántos de los futuros integrantes de este hogar son hijos y así saber un poco más sobre la familia que se mudará a la casa.

  • A partir del número de variables que finalmente se obtuvo, da referencia a que se puede obtener información de la variable respuesta sin necesidad de tener en cuenta tantas variables como las que se consideraron inicialmente, esto realmente es algo bueno, ya que no se requiere mucha información para obtener buenos resultados y a la hora de requerir recolectar nueva información será un proceso más sencillo, esto es a lo que llamamos modelos parsimoniosos los cuales siempre serán el mejor resultado.

  • Mediante los análisis realizados en el informe anterior cabe resaltar que muchas veces un hogar puede estar representado y ser estudiado de manera correcta a partir de información que viene principalmente del jefe de hogar y ser verídica.

  • En general aunque algunas veces la información no este explicita en los lugares a los que tenemos acceso, gracias a los métodos de aprendizaje estadístico podemos deducirla.

  • Cabe resaltar que en un inicio cuando se entrenaban los modelo para clasificar el número de hijos de 0 a 14, si bien los modelos basados en arboles presentaban un tiempo de ejecución corto estos solo eran capaces de predecir de 0 a 6 hijos, comparado con el modelo Knn que fue el único de los modelos probados capaz de predecir en las 14 clases.

Bibliografía