1 Introducción

El fenómeno de la habitanza en la calle representa una de las problemáticas sociales más persistentes y multidimensionales en Colombia. Más allá de la falta de vivienda, esta condición refleja la convergencia de múltiples factores estructurales como la pobreza, la exclusión social, la violencia, el consumo de sustancias psicoactivas y la ruptura de redes familiares. Ante este panorama, comprender los determinantes que inciden en la recepción de ayuda por parte de la población habitante de calle permite aportar información clave para fortalecer las políticas de atención y acompañamiento social.

El presente estudio utiliza la base de datos del Censo de Habitantes de Calle (CHC 2019), elaborado por el Departamento Administrativo Nacional de Estadística (DANE), con el propósito de analizar los factores que influyen en la probabilidad de que una persona habitante de calle reciba o no algún tipo de apoyo institucional o comunitario. Para ello, se implementaron técnicas de clasificación supervisada mediante los modelos K-Nearest Neighbors (KNN) y Regresión Logística (Logit), comparando su desempeño en términos de precisión (accuracy), sensibilidad (recall) y área bajo la curva ROC (AUC).

A través de este análisis se busca identificar los principales factores asociados al acceso a la ayuda, considerando variables demográficas, sociales y económicas. De esta manera, el trabajo ofrece una aproximación empírica que contribuye a la comprensión de las desigualdades y brechas de atención que enfrentan los habitantes de calle, así como a orientar estrategias de intervención más efectivas e inclusivas.

2 Metodología

La información analizada proviene del Censo de Habitantes de Calle (CHC 2019), una encuesta nacional del DANE que recopila datos sobre las características sociodemográficas, condiciones de vida, acceso a servicios y dinámicas de subsistencia de esta población en Colombia. Esta base de datos permite realizar estudios descriptivos y predictivos orientados a la formulación de políticas públicas.

https://microdatos.dane.gov.co/index.php/catalog/663

Variables empleadas

  • Variable dependiente (Y):
    Recibe ayuda (P26S3) — clasificada como o No. Representa si el individuo ha recibido algún tipo de apoyo social o institucional.

  • Variables independientes (X):

    1. Edad (P8R): Edad actual del individuo en años.
    2. Género (P9): Hombre o mujer.
    3. Razón para vivir en la calle (P22): Motivo principal de su situación de calle (consumo, conflictos familiares, razones económicas, entre otros).
    4. Años viviendo en la calle (P23S1R): Tiempo de permanencia en esta condición.
    5. Cómo consigue dinero (P29): Actividad económica principal para generar ingresos.

Justificación de las variables

La selección de las variables responde a su relevancia en el contexto social y económico de la población habitante de calle.

  • Se espera que la edad y los años viviendo en la calle influyan en la probabilidad de recibir ayuda, dado que la experiencia o el tiempo de exposición pueden afectar la visibilidad ante las instituciones.
  • El género puede determinar diferencias en el acceso a programas de atención debido a factores culturales y de vulnerabilidad.
  • La razón para vivir en la calle refleja las causas estructurales del fenómeno, mientras que la forma de subsistencia puede indicar niveles de integración social o marginalidad.

Modelos de clasificación aplicados

Se aplicaron dos enfoques de clasificación supervisada:

  1. K-Nearest Neighbors (KNN):
    Modelo no paramétrico que clasifica a los individuos según la cercanía con sus k vecinos más próximos en el espacio de características. Se realizaron pruebas con distintos valores de k para evaluar el comportamiento de la precisión (accuracy) y seleccionar el valor óptimo que ofreciera el mejor desempeño predictivo. Este modelo se aplicó utilizando las variables numéricas edad y años viviendo en la calle como predictores principales, bajo una división del 75 % de los datos para entrenamiento y 25 % para prueba. Además, se realizó un balanceo de clases mediante la técnica ROSE para mejorar la estabilidad del modelo.

  2. Regresión Logística (Logit):
    Modelo estadístico lineal generalizado que permite estimar la probabilidad de pertenecer a la categoría “Sí recibe ayuda” en función de las variables explicativas. A diferencia del KNN, este modelo incorpora tanto variables numéricas como categóricas (edad, años en la calle, género, razón para vivir en la calle y cómo consigue dinero), permitiendo analizar el peso individual de cada factor en la probabilidad de recibir apoyo. Se utilizó también una división de 75 % entrenamiento y 25 % prueba, aplicando balanceo con ROSE para corregir posibles desbalances en la variable dependiente.

Ambos modelos fueron evaluados y comparados en términos de exactitud (accuracy), sensibilidad, especificidad y área bajo la curva ROC (AUC), con el objetivo de determinar cuál ofrece una mejor capacidad predictiva y un equilibrio adecuado entre los errores tipo I y tipo II.

3 Análisis descriptivo

Variables Cuantitativas:

Las variables numéricas que se usaron son:

  1. Edad actual (P8R).

  2. Años viviendo en la calle (P23S1R).

1. Edad actual

• Media: 41.12 años

• Mediana: 39 años

• Desviación estándar: 13.8

Análisis descriptivo: La edad promedio de los habitantes de la calle es de aproximadamente 41 años, con una mediana cercana a los 39, lo cual nos indica que la mitad de los encuestados tiene menos de esa edad. La desviación estándar de 13.8 nos sugiere que hay una dispersión moderada, lo que evidencia que existe una amplia variedad de edades dentro de la población analizada.

Interpretación: Este resultado nos muestra que la población de los habitantes de la calle incluye tanto adultos jóvenes como personas mayores, siendo una comunidad variada en términos de la edad. Esto puede influir en las estrategias de atención social, ya que las necesidades de un adulto joven no son las mismas que las de una persona mayor que lleva muchos años en situación de calle.

2. Años viviendo en la calle

• Media: 13.03 años

• Mediana: 10 años

• Desviación estándar: 11.5

Análisis descriptivo: El promedio de tiempo que las personas llevan viviendo en la calle es de 13 años aproximadamente, aunque la mediana de 10 años nos muestra que la mitad de los encuestados ha permanecido menos de una década en esta condición. La desviación estándar de 11,5 años nos sugiere que hay una gran variabilidad, lo que nos indica que hay tanto personas con pocos años de habitanza como otras con más de 20 o 30 años en esta situación.

Interpretación: Estos resultados nos muestran la durabilidad del fenómeno de habitanza en la calle en Colombia. La duración prolongada en esta condición se puede asociar a la falta de oportunidades o a las dificultades para reintegrarse a la sociedad. Esto nos muestra que existe una necesidad de crear políticas de ayuda que faciliten procesos de rehabilitación y reintegración social a largo plazo.

Variables Categóricas:

Las variables categóricas (de tipo cualitativo) que se usaron son:

  1. Recibe ayuda (P26S3).
  2. Género (P9).
  3. Razón por la que vive en la calle (P22).
  4. Como consigue dinero (P29).

3. Recibe ayuda:

Categorías:

  1. Sí.
  2. No.

Análisis descriptivo: Una gran mayoría de la población habitante de calle no recibe ayuda institucional, lo cual demuestra un acceso limitado a programas sociales o una falta de cobertura efectiva por parte de las instituciones públicas y privadas.

Interpretación: La baja proporción de personas que reciben apoyo refleja un desafío significativo para las políticas sociales. Se requiere una mejora en los canales de atención, difusión y accesibilidad de los programas, especialmente para quienes se encuentran en condiciones extremas o en zonas periféricas.

# RECIBE AYUDA (VARIABLE CATEGORICA)
CHC_2019$recibe_ayuda <- factor(CHC_2019$recibe_ayuda,
                                levels = c(1,2),
                                labels = c("Sí", "No"))

# Tabla de recibe ayuda 
tab_recibe <- CHC_2019 %>%
dplyr::count(recibe_ayuda, name = "Frecuencia") %>%
dplyr::mutate(Porcentaje = sprintf("%.1f%%", 100 * Frecuencia / sum(Frecuencia)))

knitr::kable(tab_recibe, caption = "Recibe ayuda — Frecuencias y porcentajes")
Recibe ayuda — Frecuencias y porcentajes
recibe_ayuda Frecuencia Porcentaje
2163 21.5%
No 7915 78.5%

4. Género:

Categorías:

  1. Hombre.
  2. Mujer.

Análisis descriptivo: La mayoría de los habitantes de la calle son hombres, lo que concuerda con la tendencia nacional que hay, donde se muestra que el género masculino está más asociado o propenso a llegar a esta condición social. Las mujeres por otro lado, aunque en menor proporción, enfrentan también vulnerabilidad, y es que por lo general, sus casos son relacionados con la violencia de género o explotación.

Interpretación: Estos resultados nos muestran que existe la necesidad de crear estrategias de atención con un enfoque mayor en el género masculino. Y si bien, aunque los hombres son en mayoría quienes habitan la calle, las mujeres habitantes de calle también suelen vivir situaciones de riesgo agravadas (como abuso o prostitución forzada), lo que exige una respuesta institucional más certera.

# GENERO (VARIABLE CATEGORICA)
CHC_2019$genero <- factor(CHC_2019$genero,
                          levels = c(1,2),
                          labels = c("Hombre", "Mujer"))

#Tabla de genero
tab_genero <- CHC_2019 %>%
dplyr::count(genero, name = "Frecuencia") %>%
dplyr::mutate(Porcentaje = sprintf("%.1f%%", 100 * Frecuencia / sum(Frecuencia)))

knitr::kable(tab_genero, caption = "Género — Frecuencias y porcentajes")
Género — Frecuencias y porcentajes
genero Frecuencia Porcentaje
Hombre 8853 87.8%
Mujer 1225 12.2%

5. Razón por la que vive en la calle:

Categorías:

  1. Consumo de sustancias psicoactivas.
  2. Por gusto personal.
  3. Amenaza o riesgo para su vida o integridad física.
  4. Influencia de otras personas.
  5. Dificultades económicas.
  6. Falta de trabajo.
  7. Conflictos o dificultades familiares.
  8. Abuso sexual.
  9. Siempre ha vivido en la calle.
  10. Víctima del conflicto armado o desplazado.
  11. Otra.

Análisis descriptivo: El consumo de sustancias psicoactivas es una de las principales causas o razones para vivir en la calle, seguido de los conflictos familiares. En menor medida aparecen razones económicas, la falta de empleo y otros motivos como desplazamiento o abuso.

Interpretación: Estos resultados nos muestran que el fenómeno de la habitanza en calle está fuertemente relacionado con factores sociales y de salud mental. La alta incidencia del consumo de drogas y los problemas familiares nos sugiere la necesidad de programas integrales que combinen atención psicológica, familiar y comunitaria.

# RAZON PARA VIVIR EN LA CALLE (VARIABLE CATEGORICA)
CHC_2019$razon_vivir_en_calle <- factor(CHC_2019$razon_vivir_en_calle,
  levels = c(1,2,3,4,5,6,7,8,9,10,11),
  labels = c("Consumo de sustancias psicoactivas", "Por gusto personal",
             "Amenaza o riesgo para su vida o integridad física", "Influencia de otras personas",
             "Dificultades económicas", "Falta de trabajo", "Conflictos o dificultades familiares",
             "Abuso sexual", "Siempre ha vivido en la calle", "Victima del conflicto armado o desplazado",
             "Otra"))

# Tabla razon para vivir en la calle
tab_razon <- CHC_2019 %>%
dplyr::count(razon_vivir_en_calle, name = "Frecuencia") %>%
dplyr::arrange(dplyr::desc(Frecuencia)) %>%   # ordena de mayor a menor
dplyr::mutate(Porcentaje = sprintf("%.1f%%", 100 * Frecuencia / sum(Frecuencia)))

knitr::kable(tab_razon, caption = "Razón para vivir en la calle — Frecuencias y porcentajes")
Razón para vivir en la calle — Frecuencias y porcentajes
razon_vivir_en_calle Frecuencia Porcentaje
Consumo de sustancias psicoactivas 3739 37.1%
Conflictos o dificultades familiares 3073 30.5%
Por gusto personal 871 8.6%
Dificultades económicas 779 7.7%
Otra 478 4.7%
Falta de trabajo 423 4.2%
Victima del conflicto armado o desplazado 256 2.5%
Influencia de otras personas 195 1.9%
Amenaza o riesgo para su vida o integridad física 176 1.7%
Siempre ha vivido en la calle 58 0.6%
Abuso sexual 30 0.3%

5. Como consigue dinero:

Categorías:

  1. Limpiando vidrios, cuidando carros, tocando llantas, vendiendo en la calle u otras similares.
  2. Cantando, haciendo malabares, cuentería artesanía u otras similares.
  3. Carpintería, electricidad, construcción u otras similares.
  4. Pidiendo, retacando, mendigando.
  5. Recogiendo material reciclable.
  6. Como campanero, taquillero, vendiendo o transportando sustancias psicoactivas.
  7. Robando o atracando.
  8. Ejerciendo la prostitución.
  9. Otra.

Análisis descriptivo: La recolección de material reciclable es la fuente de ingresos más común o principal de los habitantes de la calle, seguida de los trabajos informales en la vía pública. Actividades delictivas o de riesgo, como el robo o la venta de sustancias, son minoritarias pero no se descartan en su totalidad.

Interpretación: La predominancia del reciclaje muestra que gran parte de esta población intenta generar ingresos a través de labores informales, aunque sin tener estabilidad ni seguridad. Esto nos muestra la importancia de fomentar programas de empleo inclusivo y capacitación que brinden alternativas sostenibles y legales para su subsistencia.

# COMO CONSIGUE DINERO (VARIABLE CATEGORICA)
CHC_2019$como_consigue_dinero <- factor(CHC_2019$como_consigue_dinero,
  levels = c(1,2,3,4,5,6,7,8,9),
  labels = c("Limpiando vidrios, cuidando carros, tocando llantas, vendiendo en la calle u otras similares",
             "Cantando, haciendo malabares, cuentería artesanía u otras similares",
             "Carpintería, electricidad, construcción u otras similares",
             "Pidiendo, retacando, mendigando", "Recogiendo material reciclable",
             "Como campanero, taquillero, vendiendo o transportando sustancias psicoactivas",
             "Robando o atracando", "Ejerciendo la prostitución", "Otra"))

#Tabla como consigue dinero

tab_dinero <- CHC_2019 %>%
dplyr::count(como_consigue_dinero, name = "Frecuencia") %>%
dplyr::arrange(dplyr::desc(Frecuencia)) %>%
dplyr::mutate(Porcentaje = sprintf("%.1f%%", 100 * Frecuencia / sum(Frecuencia)))

knitr::kable(tab_dinero, caption = "Cómo consigue dinero — Frecuencias y porcentajes")
Cómo consigue dinero — Frecuencias y porcentajes
como_consigue_dinero Frecuencia Porcentaje
Recogiendo material reciclable 4440 44.1%
Limpiando vidrios, cuidando carros, tocando llantas, vendiendo en la calle u otras similares 2295 22.8%
Pidiendo, retacando, mendigando 1339 13.3%
Otra 1203 11.9%
Carpintería, electricidad, construcción u otras similares 243 2.4%
Cantando, haciendo malabares, cuentería artesanía u otras similares 187 1.9%
Robando o atracando 155 1.5%
Como campanero, taquillero, vendiendo o transportando sustancias psicoactivas 108 1.1%
Ejerciendo la prostitución 108 1.1%
#Variables cuantitativas

tabla_variables_cuantitativas <- CHC_2019 %>%
summarise(
Media_Edad         = mean(edad, na.rm = TRUE),
Mediana_Edad       = median(edad, na.rm = TRUE),
DesvStd_Edad       = sd(edad, na.rm = TRUE),
Media_Años_Calle   = mean(`años_calle`, na.rm = TRUE),
Mediana_Años_Calle = median(`años_calle`, na.rm = TRUE),
DesvStd_Años_Calle = sd(`años_calle`, na.rm = TRUE)
)

#Tabla Descriptiva

knitr::kable(tabla_variables_cuantitativas, caption = "Medidas descriptivas de variables cuantitativas")
Medidas descriptivas de variables cuantitativas
Media_Edad Mediana_Edad DesvStd_Edad Media_Años_Calle Mediana_Años_Calle DesvStd_Años_Calle
41.115 39 13.82878 13.03096 10 11.51463

3.1 Grafico de barras e histogramas de la variables

3.1.1 Diagrama de barras: recibe ayuda

Análisis descriptivo: El gráfico nos muestra la distribución entre los habitantes de la calle que sí y no reciben ayuda de instituciones oficiales. La mayoría de los habitantes de calle no reciben apoyo, lo que evidencia una brecha significativa en la cobertura de programas de atención a nivel nacional.

Interpretación: Esta desigualdad nos sugiere que los mecanismos institucionales no están llegando de manera efectiva a esta población afectada. A pesar de existir programas nacionales y locales, la falta de acceso o continuidad del acompañamiento institucional limita las oportunidades de la inclusión social por parte de los habitantes de calle.

ggplot(CHC_2019, aes(x = factor(recibe_ayuda))) +
  geom_bar(fill = "#66CDAA") +
  labs(title = "Distribución de quienes reciben ayuda",
       x = "Recibe ayuda", y = "Frecuencia")

3.1.2 Histograma: edades de los habitantes de la calle

Análisis descriptivo: El rango de edad predominante se encuentra entre los 30 y 50 años, aunque también se identifican adultos mayores y jóvenes en menor proporción.

Interpretación: El hecho de que la mayoría esté en una edad productiva muestra una pérdida de capital humano y laboral. Las instituciones deberían enfocar programas de reintegración laboral, educación y salud dirigidos a estos grupo, dado su potencial para reingresar al sistema económico si se les brindan las condiciones adecuadas.

ggplot(CHC_2019, aes(x = edad)) +
geom_histogram(binwidth = 2, fill = "#ee3b3b", color = "black", alpha = 0.8) +
labs(title = "Edades de la población", x = "Edad (años)", y = "Frecuencia")

3.1.3 Histograma: años viviendo en la calle

Análisis descriptivo: La mayoría de los habitantes de calle encuestados llevan menos de 10 años viviendo en la calle, aunque existe un grupo considerable con más de 15 años, lo que indica la existencia de casos más graves o críticos de la habitanza.

Interpretación: Mientras algunos casos podrían ser recientes y potencialmente reversibles, otros reflejan trayectorias de exclusión prolongada, donde la falta de apoyo institucional ha consolidado una vida en calle. Esto sugiere la importancia de intervenciones tempranas para evitar que la situación se vuelva permanente o irreversible.

ggplot(CHC_2019, aes(x = `años_calle`)) +
geom_histogram(bins = 15, fill = "#ee1289", color = "black", alpha = 0.9) +
labs(title = "Años viviendo en la calle", x = "Años", y = "Frecuencia")

3.1.4 Diagrama de barras: razón por la que vive en la calle

Análisis descriptivo: Las causas o razones principales identificadas por el cual las personas terminan en situación de calle son dificultades económicas, falta de trabajo y conflictos familiares, seguidas del consumo de sustancias psicoactivas y la influencia de otras personas. Las razones menos frecuentes incluyen el abuso sexual o el desplazamiento.

Interpretación: Esto refleja que la pobreza y la exclusión social son los detonantes más comunes de la habitanza en calle. Además, la presencia de causas asociadas al consumo de drogas y la desintegración familiar muestra la necesidad de crear políticas que combinen atención psicosocial, salud mental y acceso al empleo.

ggplot(CHC_2019, aes(x = razon_vivir_en_calle)) +
geom_bar(fill = "#ff7f24") +
labs(title = "Razones de habitanza en calle", x = "Razón", y = "Frecuencia") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

3.1.5 Diagrama de barras: como consigue dinero

Análisis descriptivo: Los habitantes de calle recurren principalmente a actividades informales como lo son la recolección de materiales reciclables, pedir dinero o realizar oficios ocasionales. Pocos cuentan con empleos formales o ayudas económicas por parte del Estado.

Interpretación: La precariedad laboral refleja la vulnerabilidad en el ámbito económico de esta población. La ausencia de oportunidades formales alarga su habitanza en la calle y dificulta el acceso a servicios o programas de ayuda, creando así un círculo de pobreza que afecta su capacidad de reintegración en la sociedad.

ggplot(CHC_2019, aes(x = como_consigue_dinero)) +
  geom_bar(fill = "#cd950c") +
  labs(title = "Formas de conseguir dinero",
       x = "Actividad",
       y = "Frecuencia") +
  coord_flip() +  # Voltea el gráfico porque se ve muy estrello horizontal :C
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 9),
    plot.title = element_text(hjust = 0.5, face = "bold")
  )

3.1.6 Diagrama de barras: género

Análisis descriptivo: Podemos observar que hay una mayor proporción de hombres en situación de calle en comparación con las mujeres. Este patrón coincide con tendencias a nivel nacional, donde los hombres representan el grupo predominante en este ámbito.

Interpretación: La gran cantidad de hombres en esta situación de calle puede estar vinculada a factores como lo son el desempleo, la violencia, el consumo de sustancias o la ruptura de vínculos familiares. En cambio, las mujeres que viven en la calle suelen enfrentar riesgos adicionales como lo son la violencia de género, lo que requiere estrategias de atención diferentes.

ggplot(CHC_2019, aes(x = genero)) +
geom_bar(fill = "#b23aee") +
labs(title = "Distribución por género", x = "Género", y = "Frecuencia")

4 Construcción de modelos de clasificación

Objetivo general:

El estudio realizado por el grupo tuvo como objetivo predecir la probabilidad de que un habitante de calle reciba o no ayuda institucional, utilizando información sociodemográfica y contextual proveniente del Censo de Habitantes de Calle (CHC 2019) realizado por el DANE. Para ello, se construimos dos modelos de clasificación: K-Nearest Neighbors (KNN) y Regresión Logística Binaria (Logit), empleando variables relevantes al caso, como lo son la edad actual, los años viviendo en la calle, la razón por la que vive en la calle y la forma en que obtiene dinero. Los modelos fueron entrenados, evaluados y comparados mediante métricas de desempeño como lo son el accuracy, sensitivity, specificity, kappa, AUC (área bajo la curva ROC), entre otros.

A continuación se presentan los dos modelos de acuerdo con nuestra problemática acerca de las ayudas institucionales que reciben o no los habitantes de calle (basados en el censo del 2019 realizado por el DANE):

4.1 1. Modelo KNN (K-Nearest Neighbors):

El modelo k-Nearest Neighbors (kNN) es un método de clasificación supervisado que asigna una categoría a cada observación según la mayoría de sus k vecinos más cercanos en el espacio de características. En este análisis, el objetivo fue predecir la variable “Recibe ayuda” a partir de las variables “Edad” y “Años en calle”, empleando tanto un procedimiento manual de selección de k como la función train() del paquete caret en R, con técnicas de validación y balanceo de datos.

## KNN Base

set.seed(28)

index_muestra <- sample(nrow(CHC_2019),100)
index_entrena <- sample(index_muestra, 50)
index_test <- index_muestra[!index_muestra %in% index_entrena]
 
 
CHC_entrena <- CHC_2019[index_entrena, ]
CHC_test <- CHC_2019[index_test, ]
 
CHC_entrena_input  <- CHC_entrena[, c("edad", "años_calle")]
CHC_entrena_output <- CHC_entrena$recibe_ayuda    
 
CHC_test_input  <- CHC_test[, c("edad", "años_calle")]
CHC_test_output <- CHC_test$recibe_ayuda      
 
CHC_test_output_kNN <- knn(train = CHC_entrena_input,  
                              cl = CHC_entrena_output,  
                              test = CHC_test_input,  
                              k = 3)

#mean(CHC_test_output_kNN == CHC_test_output)

#table(CHC_test_output_kNN, CHC_test_output)
resultado %>% 
  ggplot() +
  aes(k, precision) +
  geom_line(color = "blue") +
  labs(title = "Precisión del Modelo KNN vs. Número de Vecinos (k)",
       x = "Número de Vecinos (k)", 
       y = "Precisión") +
  theme_minimal()

Se probó el modelo para diferentes valores de k (de 1 a 50) y se calculó la precisión (accuracy) en los datos de prueba para cada uno. El gráfico obtenido muestra un incremento inicial en la precisión, alcanzando su punto máximo alrededor de k = 13, donde la exactitud fue aproximadamente 0.80 (80%). A partir de este punto, los valores de precisión se estabilizan, lo que indica que aumentar el número de vecinos no mejora sustancialmente el desempeño del modelo.

4.2 Resultados del modelo kNN con caret

# Preparación de Datos y Balanceo
set.seed(28)
indxEntrena <- createDataPartition(y = CHC_2019$recibe_ayuda, p = 0.75, list = FALSE)

CHC_entrena2 <- CHC_2019[indxEntrena,]
CHC_test2 <- CHC_2019[-indxEntrena,]

CHC_entrena2_balance <- ROSE(recibe_ayuda ~ edad + años_calle,  
                             data = CHC_entrena2,  
                             seed = 28)$data
# table(CHC_entrena2_balance$recibe_ayuda) # Output: Se comprueba el balanceo
set.seed(28)
CHC_knnEntrenado <- train(recibe_ayuda ~ edad + años_calle,
                          data = CHC_entrena2_balance,
                          method = "knn",  
                          tuneLength = 20) # Modificado de 200 a 20
CHC_knnEntrenado
## k-Nearest Neighbors 
## 
## 7560 samples
##    2 predictor
##    2 classes: 'No', 'Sí' 
## 
## No pre-processing
## Resampling: Bootstrapped (25 reps) 
## Summary of sample sizes: 7560, 7560, 7560, 7560, 7560, 7560, ... 
## Resampling results across tuning parameters:
## 
##   k   Accuracy   Kappa     
##    5  0.5221314  0.04416423
##    7  0.5236105  0.04715749
##    9  0.5236251  0.04717369
##   11  0.5253560  0.05063913
##   13  0.5279439  0.05583367
##   15  0.5298941  0.05961283
##   17  0.5311214  0.06203442
##   19  0.5315080  0.06282454
##   21  0.5325993  0.06494174
##   23  0.5352481  0.07025964
##   25  0.5349173  0.06953097
##   27  0.5357536  0.07122606
##   29  0.5371038  0.07390434
##   31  0.5401835  0.08007132
##   33  0.5419930  0.08366916
##   35  0.5437611  0.08720052
##   37  0.5446273  0.08894411
##   39  0.5469659  0.09359309
##   41  0.5480525  0.09573543
##   43  0.5473330  0.09438554
## 
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was k = 41.
plot(CHC_knnEntrenado)

Para mejorar el desempeño, se aplicó el modelo caret::train con balanceo de clases mediante ROSE, obteniendo un conjunto de entrenamiento equilibrado (3823 “No” y 3737 “Sí”) y utilizando una partición del 75 % de los datos para entrenamiento.

Durante la validación interna, se probaron diferentes valores de k (tuneLength = 20), y el modelo óptimo fue con k = 41, con las siguientes métricas promedio de re-muestreo:

Exactitud (Accuracy) 0.548 Kappa 0.096

4.3 Evaluación mediante la matriz de confusión

La matriz de confusión del modelo final permitió analizar su desempeño detallado:

CHC_knnPrediccion <- predict(CHC_knnEntrenado, newdata = CHC_test2)

# La matriz de confusión
confusionMatrix(CHC_knnPrediccion, CHC_test2$recibe_ayuda)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   Sí   No
##         Sí  264  817
##         No  276 1161
##                                           
##                Accuracy : 0.5659          
##                  95% CI : (0.5463, 0.5854)
##     No Information Rate : 0.7855          
##     P-Value [Acc > NIR] : 1               
##                                           
##                   Kappa : 0.0556          
##                                           
##  Mcnemar's Test P-Value : <2e-16          
##                                           
##             Sensitivity : 0.4889          
##             Specificity : 0.5870          
##          Pos Pred Value : 0.2442          
##          Neg Pred Value : 0.8079          
##              Prevalence : 0.2145          
##          Detection Rate : 0.1048          
##    Detection Prevalence : 0.4293          
##       Balanced Accuracy : 0.5379          
##                                           
##        'Positive' Class : Sí              
## 

De esta matriz se derivan los siguientes indicadores:

  • Precisión global (Accuracy): 0,5659
  • Sensibilidad (Recall para “Sí”): 0,4889
  • Especificidad: 0,5870
  • Precisión o Valor Predictivo Positivo (PPV): 0,2442
  • Balanced Accuracy: 0,5379

El modelo acertó en el 56,59% de los casos totales. Su capacidad para identificar correctamente a quienes sí reciben ayuda es moderada (sensibilidad 48,89%), mientras que logra una mejor identificación de quienes no la reciben (especificidad 58,7%). El bajo valor de precisión (24,42%) indica una presencia considerable de falsos positivos. En conjunto, las métricas muestran que el modelo tiene un rendimiento limitado en la predicción individual, aunque conserva cierta capacidad de generalización útil para reconocer tendencias globales.

4.4 Curva ROC con caret

La curva ROC muestra el desempeño del modelo clasificatorio —en este caso, kNN— al comparar:

  • Eje X: tasa de falsos positivos (1 - especificidad)
  • Eje Y: tasa de verdaderos positivos (sensibilidad)

Cada punto de la curva representa un umbral de probabilidad diferente, es decir, el punto en el cual el modelo decide si clasifica una observación como “” o “No”.

# CURVA ROC 

prob_knnPrediccion <- predict(CHC_knnEntrenado, newdata = CHC_test2, type = "prob")

if (!is.null(prob_knnPrediccion) && "Sí" %in% colnames(prob_knnPrediccion)) {
  pred1 <- prediction(prob_knnPrediccion[["Sí"]],
                      ifelse(CHC_test2$recibe_ayuda == "Sí", 1, 0))
  perf1 <- performance(pred1, "tpr", "fpr")
  
  plot(perf1,
       main = "Curva ROC - KNN (caret) - CHC_2019",
       col = "blue", 
       lwd = 2)
  abline(a = 0, b = 1, lty = 2, col = "red")
} else {
  message("No se pudieron generar probabilidades para la curva ROC.")
}

La curva ROC del modelo KNN entrenado con el conjunto CHC_2019 muestra un desempeño bajo. La curva se aproxima a la diagonal, lo que indica una capacidad de discriminación apenas superior al azar. Esto se corrobora con un AUC estimado cercano a 0.55 y una precisión general del 56 %.

4.5 Modelo Logit (Regresión Logística Binaria):

El modelo Logit permitió analizar la relación entre las variables Edad y Años en calle con la probabilidad de que una persona reciba ayuda dentro de la población de habitantes de calle. Los coeficientes estimados indican la dirección e intensidad de la asociación entre cada variable independiente y la variable dependiente, expresada en términos de log-odds (razones de probabilidades).

Significancia de los predictores

Los resultados del modelo muestran que varias variables son estadísticamente significativas (p < 0.05) y, por tanto, influyen de forma relevante sobre la probabilidad de recibir ayuda:

  • Edad (p = 0.0028): un mayor valor en la edad aumenta ligeramente la probabilidad de recibir ayuda, manteniendo las demás variables constantes.

  • Años viviendo en la calle (p < 0.001): a medida que aumenta el tiempo en la calle, la probabilidad de recibir ayuda también aumenta, posiblemente por una mayor visibilidad o experiencia en gestionar recursos de asistencia.

  • Género (Mujer, p < 0.001): las mujeres tienen una probabilidad significativamente mayor de recibir ayuda en comparación con los hombres.

  • Razones para vivir en la calle:

  • Amenaza o riesgo para su vida o integridad física (p < 0.001) y víctima del conflicto armado o desplazado (p < 0.001) incrementan la probabilidad de recibir ayuda.

  • Por el contrario, por gusto personal, dificultades económicas y falta de trabajo reducen dicha probabilidad (todas con p < 0.001).

  • Forma de conseguir dinero:

  • Recoger material reciclable (p < 0.001) y ejercer la prostitución (p < 0.001) disminuyen significativamente la probabilidad de recibir ayuda.

  • En cambio, la categoría otra forma de conseguir dinero (p < 0.001) muestra una relación positiva con recibir ayuda.

4.6 Evaluacion mediante la matriz de confusion

# MODELO LOGIT BALANCEADO (Regresión logística binaria)


library(caret)
library(ROSE)
library(pROC)

set.seed(28)

# División entrenamiento / prueba (igual que en KNN)

indxEntrena <- createDataPartition(y = CHC_2019$recibe_ayuda, p = 0.75, list = FALSE)

CHC_entrena_logit <- CHC_2019[indxEntrena, ]
CHC_test_logit <- CHC_2019[-indxEntrena, ]


# BALANCEAR LOS DATOS DE ENTRENAMIENTO

# Aquí se aplica el balanceo ROSE sobre el conjunto de entrenamiento.
# Esto crea un conjunto equilibrado entre las clases "Sí" y "No".

CHC_entrena_logit_balance <- ROSE(
  recibe_ayuda ~ edad + años_calle + genero + razon_vivir_en_calle + como_consigue_dinero,
  data = CHC_entrena_logit,
  seed = 28
)$data

# Verificamos la nueva distribución de clases

#table(CHC_entrena_logit_balance$recibe_ayuda)


# ENTRENAMIENTO DEL MODELO LOGIT BALANCEADO


modelo_logit_balance <- glm(
  recibe_ayuda ~ edad + años_calle + genero + razon_vivir_en_calle + como_consigue_dinero,
  data = CHC_entrena_logit_balance,
  family = binomial(link = "logit")
)

#summary(modelo_logit_balance)


# PREDICCIÓN Y EVALUACIÓN

# Predicción de probabilidades en el conjunto de prueba

prob_logit_balance <- predict(modelo_logit_balance, newdata = CHC_test_logit, type = "response")

# Convertimos probabilidades a clases (Sí / No)

pred_logit_balance <- ifelse(prob_logit_balance >= 0.5, "Sí", "No")
pred_logit_balance <- factor(pred_logit_balance, levels = c("Sí", "No"))

# Matriz de confusión

conf_matrix_logit_balance <- confusionMatrix(
  pred_logit_balance,
  CHC_test_logit$recibe_ayuda,
  positive = "Sí"
)
conf_matrix_logit_balance
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   Sí   No
##         Sí  276  697
##         No  264 1281
##                                          
##                Accuracy : 0.6183         
##                  95% CI : (0.599, 0.6374)
##     No Information Rate : 0.7855         
##     P-Value [Acc > NIR] : 1              
##                                          
##                   Kappa : 0.1229         
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.5111         
##             Specificity : 0.6476         
##          Pos Pred Value : 0.2837         
##          Neg Pred Value : 0.8291         
##              Prevalence : 0.2145         
##          Detection Rate : 0.1096         
##    Detection Prevalence : 0.3864         
##       Balanced Accuracy : 0.5794         
##                                          
##        'Positive' Class : Sí             
## 
  • Exactitud (Accuracy): 0,6183, lo que significa que el modelo clasifica correctamente el 61.8 % de los casos.

  • Sensibilidad (Recall): 0,5111, indicando que el 51 % de las personas que realmente reciben ayuda fueron correctamente identificadas.

  • Especificidad: 0,6476, por lo que el 64,76 % de quienes no reciben ayuda fueron correctamente clasificados.

  • Valor predictivo positivo (Precisión): 0,2837, relativamente bajo (28,37%), lo que nos sugiere que el modelo tiende a sobreestimar algunos casos positivos.

  • Kappa: 0,1229, mostrando un acuerdo leve (12,29%) entre las predicciones del modelo y los valores reales (más allá del azar).

  • Balanced Accuracy: 0,5794, que combina sensibilidad y especificidad, indica un rendimiento moderado pero mejor que el azar (57,94%).

4.7 Curva ROC

# CURVA ROC y AUC

roc_logit_balance <- roc(CHC_test_logit$recibe_ayuda, prob_logit_balance, levels = c("No", "Sí"))

invisible(roc_logit_balance)
plot(roc_logit_balance, col = "darkorange", lwd = 2, main = "Curva ROC - Modelo Logit Balanceado")

auc_logit_balance <- auc(roc_logit_balance)
auc_logit_balance
## Area under the curve: 0.6268

El Área Bajo la Curva (AUC) obtenida fue de 0.6268, lo cual sugiere un desempeño aceptable, pero limitado, ya que un AUC igual a 0.5 representa un modelo sin capacidad de clasificación, mientras que valores cercanos a 1 indican un modelo con excelente desempeño. Por lo tanto, el valor alcanzado refleja que el modelo logra distinguir entre ambas clases mejor que el azar, aunque con una precisión moderada.

5 Comparacion de resultados

# --- BLOQUE DE COMPARACIÓN DE MODELOS ---

# 1. Recopilar Métricas de KNN (del modelo de caret)
cm_knn <- confusionMatrix(CHC_knnPrediccion, CHC_test2$recibe_ayuda, positive = "Sí")
acc_knn <- cm_knn$overall['Accuracy']
sens_knn <- cm_knn$byClass['Sensitivity']
spec_knn <- cm_knn$byClass['Specificity']

# 2. Recopilar Métricas de Logit Balanceado (del modelo glm con ROSE)
acc_logit <- conf_matrix_logit_balance$overall['Accuracy']
sens_logit <- conf_matrix_logit_balance$byClass['Sensitivity']
spec_logit <- conf_matrix_logit_balance$byClass['Specificity']

# 3. Calcular Curvas ROC y AUC (con pROC para ambos)
library(pROC)

# ROC para KNN (usando las probabilidades de caret)
roc_knn <- roc(CHC_test2$recibe_ayuda, prob_knnPrediccion[['Sí']], levels = c("No", "Sí"))
auc_knn <- auc(roc_knn)

# ROC para Logit balanceado (usando las probabilidades del glm con ROSE)
roc_logit <- roc(CHC_test_logit$recibe_ayuda, prob_logit_balance, levels = c("No", "Sí"))
auc_logit <- auc(roc_logit)

# 4. Crear Tabla Comparativa
library(knitr)

metricas <- c("Accuracy", "Sensitivity", "Specificity", "AUC")
KNN <- c(acc_knn, sens_knn, spec_knn, auc_knn)
Logit_Balanceado <- c(acc_logit, sens_logit, spec_logit, auc_logit)

tabla_comparativa <- data.frame(
  Metrica = metricas,
  KNN = KNN,
  Logit_Balanceado = Logit_Balanceado
)

# Imprimir tabla bonita como buenos ingenierios uwu

kable(
  tabla_comparativa,
  caption = "Comparación de Modelos: KNN vs Logit Balanceado (ROSE)",
  align = c("l", "c", "c"),
  format = "html",
  table.attr = 'style="width:60%; margin-left:auto; margin-right:auto; border-collapse:collapse; font-size:13px;"'
)
Comparación de Modelos: KNN vs Logit Balanceado (ROSE)
Metrica KNN Logit_Balanceado
Accuracy Accuracy 0.5659253 0.6183479
Sensitivity Sensitivity 0.4888889 0.5111111
Specificity Specificity 0.5869565 0.6476239
AUC 0.5650067 0.6268107

A continuación se realiza una comparación en base a los resultados obtenidos en el modelo KNN y Logit:

Aquí se pone la parte del código de comparación que da una tabla con los resultados de ambos modelos Primero se pone la tabla anterior para responder las siguientes preguntas:

A) ¿Cuál tiene mejor exactitud (accuracy)?

El modelo Logit tiene una exactitud del 61,83%, comparado con el 56,59% del modelo KNN, por lo que el modelo Logit presenta un mejor desempeño global al clasificar correctamente un mayor porcentaje de los casos totales. Esto significa que, en promedio, el modelo Logit logra una predicción más precisa de quiénes reciben o no ayuda institucional, aunque la diferencia no es muy amplia.

B) ¿Cuál logra mayor sensibilidad o detecta mejor los casos positivos?

El modelo KNN tiene una sensibilidad del 48,89%, comparado con el 51,11% del modelo Logit, lo que indica que el modelo KNN identifica ligeramente mejor a las personas que realmente reciben ayuda institucional. Esta diferencia, aunque pequeña, sugiere que el KNN tiene una leve ventaja en detectar los casos positivos (los que sí reciben ayuda).

C) ¿Cuál tiene mejor AUC?

El modelo Logit tiene un AUC del 62,68%, mientras que el modelo KNN tiene un AUC del 56,5%, lo que significa que el modelo Logit tiene una mayor capacidad para distinguir entre quienes reciben ayuda y quienes no la reciben. En otras palabras, el Logit logra una mejor discriminación entre las dos clases, lo que se traduce en un rendimiento predictivo más estable y confiable.

D) ¿Cuál logra mayor especificidad o detecta mejor los casos negativos?

El modelo Logit tiene una especificidad del 64,76%, mientras que el del modelo KNN es del 58,7%, lo que implica que el Logit identifica con mayor eficacia a las personas que no reciben ayuda institucional. Esto refuerza su capacidad para reconocer correctamente los casos negativos, reduciendo el número de falsos positivos.

E) ¿Cuál logra mayor Balanced Accuracy? El modelo Logit tiene un Balanced Accuracy del 57,94%, mientras que el del modelo KNN es del 53,79%, lo que implica que el Logit logra un equilibrio más adecuado entre la sensibilidad y la especificidad, siendo más consistente en el reconocimiento tanto de los casos positivos como negativos.

F) ¿Cuál logra mayor Kappa?

El modelo KNN tiene un valor de Kappa del 5,56%, mientras que el del modelo Logit es del 12,29%, lo que implica que el Logit presenta un mayor nivel de acuerdo entre las predicciones del modelo y los valores reales, superando ligeramente al KNN. Un valor de Kappa más alto indica una mejor concordancia más allá del azar.

5.1 ¿Qué modelo sería más recomendable para esta problemática y por qué?:

# 5. Graficar Curvas ROC Superpuestas 
# Inicia el gráfico con la primera curva (Logit balanceado)
plot(roc_logit,
     col = "darkorange",
     lwd = 2,
     main = "Curvas ROC Comparativas: KNN vs. Logit Balanceado (ROSE)")

# Añade la segunda curva (KNN)
plot(roc_knn,
     col = "blue",
     lwd = 2,
     add = TRUE)

# Añade una leyenda
legend("bottomright",
       legend = c(paste("Logit Balanceado (AUC =", round(auc_logit, 3), ")"),
                  paste("KNN (AUC =", round(auc_knn, 3), ")")),
       col = c("darkorange", "blue"),
       lwd = 2,
       cex = 0.8)

En este caso, el modelo Logit presenta un área bajo la curva (AUC = 0,6268) ligeramente superior al del modelo KNN (AUC = 0,5650). Esto indica que el modelo Logit tiene una mejor capacidad predictiva global y discrimina con mayor precisión entre las clases. Por tanto, aunque las diferencias no son extremadamente amplias, el modelo Logit supera de forma consistente al modelo KNN, mostrando un mejor equilibrio entre la sensibilidad y la especificidad de nuestra problemática. Esto nos sugiere que la técnica de balanceo empleada contribuyó a mejorar la clasificación de la clase minoritaria, lo cual se puede ver en un desempeño más robusto del modelo Logit frente al KNN.

Tomando en cuenta lo anterior, el modelo Logit es el más recomendable para esta problemática, y es que aunque el modelo KNN presenta una sensibilidad apenas superior, el modelo Logit muestra un rendimiento más equilibrado y estable, con una mayor exactitud, especificidad, AUC, Balanced Accuracy y Kappa, lo que nos permite comprender mejor la relación y el peso de las variables sobre la probabilidad de recibir ayuda institucional.

En un contexto social como el de los habitantes de calle, donde se busca tanto predecir el cómo entender los factores que influyen en el acceso a programas de apoyo, el modelo Logit resulta más útil para poder orientar políticas y estrategias institucionales, ya que explica de forma más clara cómo las variables sociodemográficas inciden en la recepción de ayuda.

6 Conclusiones generales

1. Ambos modelos nos presentan desempeños moderados, con un KNN ligeramente superior en capacidad predictiva.

2. El modelo Logit ofrece una mejor comprensión del fenómeno, al permitir interpretar el peso de cada variable independiente sobre la respuesta.

3. Las variables “años viviendo en la calle” y “edad” son las que más influyen en la probabilidad de recibir ayuda institucional, lo que implica que las trayectorias más largas en la calle tienden a reducir las posibilidades de tener acceso a un apoyo formal.

4. Como grupo se llegó a la conclusión de que el modelo ajustado sí logró responder al objetivo del estudio que se planteó, permitiéndonos predecir la probabilidad de que un habitante de calle reciba ayuda institucional a partir de sus características sociodemográficas. El modelo Logit nos dio un mejor desempeño general (Accuracy del 61,83% y AUC del 62,68%) en comparación al del modelo KNN, lo que nos indica que hay una capacidad moderada para distinguir entre quienes reciben y no reciben ayuda. Aunque la sensibilidad y el Kappa fueron bajos, reflejando cierta dificultad para identificar los casos positivos, los resultados nos confirman que las variables analizadas (edad, años viviendo en la calle, género, razón de habitanza en la calle y forma de conseguir dinero) aportan información útil para entender el acceso al apoyo institucional. Por lo tanto, el modelo sí cumple el objetivo y puede servirnos como herramienta orientadora para mejorar estrategias y políticas de atención hacia esta población.

6.1 Estrategias o recomendaciones basadas en los hallazgos:

1. Ampliar las variables del modelo incorporando factores sociales (redes de apoyo, antecedentes familiares, salud mental, zona geográfica, consumo de sustancias, entre otros).

2. Reforzar las estrategias de intervención institucional dirigidas a personas con más años en situación de calle, dado que el modelo sugiere menor acceso a ayuda en este grupo.

3. Implementar campañas de sensibilización que fortalezcan el vínculo entre instituciones de apoyo y la población más vulnerable.