1 Introducción

La inclusión financiera es un factor clave para el desarrollo económico y la reducción de la pobreza, por tal motivo, se ha convertido en un tema cada vez más importante en Colombia. Este concepto se encuentra relacionado con la posibilidad que tienen las personas y empresas de acceder a diversos productos y servicios financieros útiles y asequibles como cuentas bancarias, créditos, transferencias o medios de ahorro (BBVA, 2024).

Tener acceso a estos servicios no solo atiende a ciertas necesidades o facilita las actividades económicas del día a día, sino que también puede mejorar la calidad de vida, reducir algunas desigualdades sociales e impulsar el desarrollo. Además, la inclusión financiera es considerada por el Banco Mundial como un elemento facilitador para promover la prosperidad compartida.

La tenencia de cuentas de ahorro, en particular, se destaca como uno de los pilares fundamentales de la inclusión financiera: no solo permite a las personas guardar dinero, enviar y recibir pagos, sino que también funciona como vía de acceso a otros servicios financieros (Grupo Banco Mundial, 2022).

Durante el año 2022, periodo al que corresponde la base de datos utilizada, el tema de la inclusión financiera tomó aún más relevancia debido al proceso de recuperación después de la pandemia por COVID-19. En ese contexto, el uso de herramientas digitales y servicios financieros virtuales aumentó considerablemente, haciendo que factores como el acceso a internet, el nivel educativo o la zona de residencia afectarán de manera importante las oportunidades de acceso al sistema financiero.

Por esta razón, en el presente trabajo se analiza la inclusión financiera en Colombia a partir de variables sociodemográficas y económicas. Estas variables fueron seleccionadas porque permiten entender mejor qué características y como pueden influir en que una persona tenga o no acceso a una cuenta de ahorro. Para ello, se utilizarán dos modelos de clasificación, con el fin de identificar patrones y estimar la probabilidad de la inclusión financiera de los individuos encuestados.

2 Metodología

La metodología se centró en la aplicación de un enfoque basado en el aprendizaje supervisado, haciendo uso de datos (de la tercera toma del estudio) de la Encuesta de Demanda de Inclusión Financiera 2022 en Colombia. El enfoque busca clasificar la tenencia de cuentas de ahorro (variable binaria: sí o no), considerado comúnmente como el pilar fundamental de la inclusión financiera, a partir de factores sociodemográficas y económicas relacionadas con el acceso a servicios financieros de los encuestados.

La metodología se articula en cuatro etapas: preprocesamiento de los datos, análisis descriptivo, modelado con los algoritmos knn (K-vecinos más cercanos) y regresión logística, y una comparación entre ambos algoritmos.

2.1 Datos y su origen

Los datos utilizados para el enfoque tienen su origen en la Encuesta de Demanda de Inclusión Financiera 2022, realizada por el programa Banca de las Oportunidades, perteneciente al Gobierno Nacional y administrado por Bancóldex (Banco de Desarrollo Empresarial).

Dicho estudio busca identificar, a partir de las percepciones y condiciones de los encuestados, brechas existentes en el acceso al sistema financiero y en general, el bienestar financiero de los colombianos. Todo esto, con el fin de brindar un panorama completo acerca de los avances, retos y oportunidades en materia de inclusión financiera (Banca de las Oportunidades , s.f.).

De las 5610 observaciones, se eliminaron los valores nulos y se realizó un muestreo estratificado, dividiendo el número de registros de acuerdo a la tenencia de cuenta de ahorro, seguido de un muestreo aleatorio simple: se obtuvo una muestra de 3000 observaciones, siendo lo suficientemente representativa, proporcional y amplia para entrenar a los modelos.


2.2 Descripción de variables utilizadas

Variable dependiente

  • La variable Y elegida corresponde a la tenencia (o no) de una cuenta de ahorro, una variable binaria nominal. Indica si una persona posee una cuenta de ahorro en una entidad financiera formal (cooperativas, bancos o corporaciones de ahorro). Tradicionalmente, la cuenta de ahorros es el producto más usado para ahorrar y disponer de dinero de forma rápida y segura (DAVIbank, s.f.), por lo que es comúnmente utilizado como proxy de la inclusión financiera.

Variables independientes

  • Ingreso promedio (COP): variable cuantitativa continua. Indica el ingreso mensual promedio percibido del individuo, representando la capacidad de generación de recursos. Es considerado como unos de los principales determinantes de la inclusión financiera, dado que explica la capacidad económica. Mayores ingresos facilitan el acceso y la capacidad de ahorrar en una cuenta.
  • Edad (años): variable cuantitativa continua (también categorizada en rangos). Indica los años cumplidos al momento de responder la encuesta. Esta variable permite analizar el comportamiento financiero a lo largo del ciclo de vida y captura las diferentes necesidades financieras en las distintas etapas generacionales. Mientras que los jóvenes poseen poca experiencia financiera, los adultos suelen tener mayor estabilidad económica y una visión más clara sobre la importancia del ahorro.
  • Nivel educativo: variable cualitativa ordinal. Expresa el máximo grado de formación alcanzado por la persona. Indica el nivel del capital humano y el conocimiento sobre productos financieros. Se esperaría que, a niveles educativos más altos, aumente la probabilidad de tener una cuenta.
  • Género: variable cualitativa nominal de inclusión social. Refleja la ausencia o existencia de brechas en cuanto al acceso al sistema financiero, captura la equidad de género e indica las dinámicas diferenciadas entre hombres y mujeres. Junto con la edad, representan el perfil demográfico de las personas encuestadas.
  • Acceso a internet: variable cualitativa nominal. Indica la disponibilidad de conexión a internet en el hogar o a través de dispositivos personales y captura el impacto de la digitalización financiera. Esta variable actúa como promotora moderna de la inclusión: tener internet facilita abrir y usar cuentas.
  • Zona de residencia: variable cualitativa. Indica, reúne y clasifica a las personas de acuerdo a los diferentes tipos de zonas en las que residen, capturando así, las diferencias territoriales en infraestructura y costumbres financieras. Permite entender cómo el territorio influye en el acceso a los servicios bancarios, ya que la diferencia entre infraestructura y conectividad puede afectar la decisión de tener una cuenta de ahorros.


2.3 Preprocesamiento de los datos

library(caret)
library(ISLR)
library(readxl)
library(tidyverse)
library(themis)
library(class)
library(ROCR)
library(pROC)
library(ggplot2)
library(dplyr)
library(tidyr)
library(ggthemes)
library(colorspace)
library(scales)
library(showtext)
library(webr)
library(ggtext)
library(forcats)
library(knitr)
library(kableExtra)

font_add("segoe", regular = "C:/Windows/Fonts/segoeui.ttf") 
font_add("segoe_b", regular = "C:/Windows/Fonts/segoeuib.ttf")
showtext_auto()



Base_de_datos_Taller_2 <- read_excel("Base de datos - Taller 2.xlsx")

Previo al modelado, se realizaron ciertas transformaciones sobre las variables independientes. Las variables numéricas como el ingreso promedio y la edad se estandarizaron mediante el método de normalización por mínimos y máximos, transformando los valores en un rango de 0 a 1, mediante la siguiente fórmula:

\[Normalizacion = \frac{X - X_{min}}{X_{max} - X_{min}}\]

El nivel educativo, al ser una variable ordinal, se codifico de manera ascendente del 0 al 6, con cada número entero representando a los siguientes niveles educativos, respectivamente: ninguno, primaria, secundaria, técnico, tecnología, pregrado y posgrado. Posteriormente, se aplicó el método de normalización por mínimos y máximos.

En cambio, variables cualitativas nominales como género y acceso a internet se transformaron mediante la codificación binaria, asignándoles un valor de 0 o 1: en el caso de la variable género, el valor 0 se le asigna al género masculino, mientras que el 1 al femenino. Para el caso del acceso a internet, 0 corresponde a los individuos que no tienen acceso a internet y 1 a los que si tienen acceso.

Finalmente, está la variable zona, que se dividió en 4 subvariables dummies: ciudad, intermedio, rural y rural disperso. En cada subvariable, el valor 0 se asigna si el individuo no pertenece a esa zona geográfica, mientras que el 1 se asigna si el individuo si pertenece.

La base de datos resultante fue dividida aleatoriamente en un conjunto de entrenamiento y otro de prueba, utilizando el 70% de las observaciones para entrenar el modelo y el 30% restante para evaluar su desempeño predictivo. Adicionalmente, se hizo uso de set.seed(23), permitiendo garantizar la reproducibilidad de los resultados obtenidos.


2.4 Descripción de los algoritmos para el modelado

  • kNN o el algoritmo del K-vecino más cercano: es un modelo que usa la proximidad para comparar un punto de datos con un conjunto de datos, previamente entrenado y memorizado para realizar predicciones. Este algoritmo funciona bajo el supuesto de “cada oveja con su pareja”, realizando predicciones basadas en el promedio de la cantidad k de vecinos (valores) más cercanos al punto de búsqueda. Dado su gran capacidad de adaptabilidad, puede utilizarse en muchos de los campos del conocimiento, incluido finanzas (Elastic, s.f.).

  • Regresión logística o logit: es un modelo que busca predecir la probabilidad de que ocurra un evento de interés, en este caso, si el individuo encuestado tiene o no cuenta de ahorros, conociendo los valores de las variables predictoras. A diferencia de un modelo de regresión lineal, que se utiliza para predecir una variable continua, logit predice una variable categórica binaria. Si la probabilidad estimada es mayor a un umbral especifico (comúnmente 0,5) el modelo clasifica las observaciones dentro del evento de interés. La variable dependiente adopta entonces, valores de 0 y 1, representando, respectivamente el fracaso o éxito del evento.

Al igual que el algoritmo kNN, logit destaca en el área de finanzas, dado que es apropiado para modelos que cubren asuntos de toma de decisiones y análisis relacionados a la economía (iuvity, s.f.).

3 Análisis descriptivo

3.1 Estado de la inclusión financiera en la muestra

datos_porcentaje <- Base_de_datos_Taller_2 %>% 
  count(Cuenta_ahorros) %>% 
  mutate(porcentaje = n / sum(n) * 100) %>%
  mutate(Cuenta_ahorros = recode(Cuenta_ahorros,
                                 "NO" = "No", 
                                 "SÍ" = "Sí"))
Ahorros <- ggplot(datos_porcentaje, aes(x = Cuenta_ahorros, y = porcentaje, fill = Cuenta_ahorros)) +
  geom_col(width = 0.75) +
  geom_richtext(aes(label = paste0(round(porcentaje, 1), "%"),),
            color = c("#A7BFC7","#2A5674"), 
            fill = NA, label.color = NA, hjust = 0.5, size = 10, show.legend = FALSE,
            family = "segoe_b",
            vjust = 0) +
  labs(
    title = "¿Cuántos colombianos tienen cuenta de ahorros?",
    subtitle = "Sólo 4 de cada 10 personas de la muestra están bancarizadas",
    x = NULL,
    y = NULL) +
  
  scale_fill_manual(values = c("#A7BFC7","#2A5674")) +
  theme_minimal()+
  scale_y_continuous(limits = c(0, 100), 
                     breaks = seq(0, 100, by = 20),
                     labels = function(x) paste0(x, "%")) +
  
  theme(plot.title = element_text(size = 35, color = "gray21", family = "segoe_b", 
                                  hjust = 0),
        plot.title.position = "plot",
        
        plot.subtitle = element_text(size = 28, color = "gray40", family = "segoe", 
                                     hjust = 0, margin = margin(b = 10)),
        plot.subtitle.position = "plot",
        
        axis.text.y = element_markdown(size = 25, color = "gray40", hjust = 1),
        axis.text.x = element_markdown(size = 25, color = "gray21", hjust = 1),
        legend.text = element_blank(),
        legend.title = element_blank(),
        
        axis.line = element_line(color = "black"), 
        panel.grid = element_blank(), 
        legend.position = "none")  
Ahorros

La distribución de la variable de estudio evidencia que el 60% de las personas incluidas en la muestra no posee cuenta de ahorros, mientras que el 40% si se encuentra bancarizada: aunque la brecha entre estos 2 aspectos no es totalmente significativa (600 personas), estos resultados sugieren que todavía persisten retos en cuanto a inclusión financiera, lo que podría dar paso al diseño de productos y políticas que favorezcan la integración.

Pese a lo anterior, esta distribución no se encuentra totalmente desbalanceada, lo que permite hacer uso de los modelos sin necesidad de remuestreo. Resulta pertinente, entonces, analizar si las variables presentan diferencias entre los incluidos y no incluidos.


3.2 Caracterización general de la muestra

Tabla_estadisticas <- data.frame(
  Variable = c("Ingreso promedio", "Edad"),
  Min = c(
    min(Base_de_datos_Taller_2$Ingreso_promedio, na.rm = TRUE),
    min(Base_de_datos_Taller_2$Edad, na.rm = TRUE)),
  Max = c(
    max(Base_de_datos_Taller_2$Ingreso_promedio, na.rm = TRUE),
    max(Base_de_datos_Taller_2$Edad, na.rm = TRUE)),
  Mediana = c(
    median(Base_de_datos_Taller_2$Ingreso_promedio, na.rm = TRUE),
    median(Base_de_datos_Taller_2$Edad, na.rm = TRUE)),
  Promedio = c(
    mean(Base_de_datos_Taller_2$Ingreso_promedio, na.rm = TRUE),
    mean(Base_de_datos_Taller_2$Edad, na.rm = TRUE)),
  Desviacion_Estandar = c(
    sd(Base_de_datos_Taller_2$Ingreso_promedio, na.rm = TRUE),
    sd(Base_de_datos_Taller_2$Edad, na.rm = TRUE)))

options(scipen = 999)

colnames(Tabla_estadisticas) <- c("Variable", "Min", "Max", "Mediana", "Promedio", "Desviación")

kable(Tabla_estadisticas,
      align = c('l','c', 'c', 'c', 'c', 'c'),
      format = "html", 
      caption = "Estadísticas descriptivas de variables numéricas", digits = 0) %>%
  kable_styling(full_width = FALSE, html_font = "Segoe UI", position = "left",
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, color = "#3C4967", bold = TRUE) %>%
  row_spec(1:2, color = "#295675")
Estadísticas descriptivas de variables numéricas
Variable Min Max Mediana Promedio Desviación
Ingreso promedio 250000 5000000 875000 1203042 1108401
Edad 18 70 41 42 15
En esta tabla, se puede observar que los ingresos de las personas de la muestra son muy variados, ya que hay personas con ingresos bajos y otras con ingresos mucho más altos. Esto muestra que existen diferencias económicas importantes dentro de la población analizada. Además, las edades van desde los 18 hasta los 70 años, con un promedio cercano a los 42 años, lo que permite incluir personas de diferentes etapas de la vida dentro del estudio.


Tabla_frecuencias <- bind_rows(
  
  Base_de_datos_Taller_2 %>%
    count(Nivel_educativo) %>%
    mutate(
      Nivel_educativo = case_when(
        Nivel_educativo == 0 ~ "Ninguno",
        Nivel_educativo == 1 ~ "Primaria",
        Nivel_educativo == 2 ~ "Secundaria",
        Nivel_educativo == 3 ~ "Técnico",
        Nivel_educativo == 4 ~ "Tecnología",
        Nivel_educativo == 5 ~ "Pregrado",
        Nivel_educativo == 6 ~ "Posgrado")) %>%
    
    mutate(
      Categoria = as.character(Nivel_educativo),
      Frecuencia = n,
      Porcentaje = round(n / sum(n) * 100, 2),
      Variable = "Nivel educativo") %>%
    select(Variable, Categoria, Porcentaje),
  
  Base_de_datos_Taller_2 %>%
    count(`Acceso_internet`) %>%
    mutate(
      `Acceso_internet` = case_when(
        `Acceso_internet` == 0 ~ "No tiene acceso",
        `Acceso_internet` == 1 ~ "Tiene acceso")) %>%
    mutate(
      Categoria = as.character(`Acceso_internet`),
      Frecuencia = n,
      Porcentaje = round(n / sum(n) * 100, 2),
      Variable = "Acceso a internet") %>%
    select(Variable, Categoria, Porcentaje),
  
  Base_de_datos_Taller_2 %>%
    mutate(
      Genero = case_when(
        Genero == 0 ~ "Masculino",
        Genero == 1 ~ "Femenino")) %>%
    
    count(Genero) %>%
    mutate(
      Categoria = as.character(Genero),
      Frecuencia = n,
      Porcentaje = round(n / sum(n) * 100, 2),
      Variable = "Género") %>%
    select(Variable, Categoria, Porcentaje),
  
  Base_de_datos_Taller_2 %>%
    mutate(
      Zona = case_when(
        Zona_Ciudad == 1 ~ "Ciudad",
        Zona_Intermedia == 1 ~ "Intermedio",
        Zona_Rural == 1 ~ "Rural",
        Zona_Rural_disperso == 1 ~ "Rural disperso")) %>%
    count(Zona) %>%
    mutate(
      Categoria = as.character(Zona),
      Frecuencia = n,
      Porcentaje = round(n / sum(n) * 100, 2),
      Variable = "Zona") %>%
    select(Variable, Categoria, Porcentaje))


kable(
  Tabla_frecuencias %>% select(-Variable),
  caption = "Tabla 2. Frecuencia de variables categóricas",
  col.names = c("Categoría", "%")) %>%
  
  kable_styling(full_width = FALSE,
                bootstrap_options = c("striped", "hover"),
                html_font = "Segoe UI", position = "left") %>%
  
  row_spec(0, color = "#3C4967", bold = TRUE) %>%
  row_spec(1:15, color = "#295675") %>%
  
  pack_rows(
    index = c("Nivel educativo" = 7, "Acceso a internet" = 2, "Género" = 2, "Zona" = 4),
    label_row_css = "color: #3C4967")
Tabla 2. Frecuencia de variables categóricas
Categoría %
Nivel educativo
Ninguno 2.40
Primaria 20.80
Secundaria 44.73
Técnico 12.83
Tecnología 5.70
Pregrado 11.27
Posgrado 2.27
Acceso a internet
No tiene acceso 30.50
Tiene acceso 69.50
Género
Femenino 53.63
Masculino 46.37
Zona
Ciudad 60.43
Intermedio 16.93
Rural 14.17
Rural disperso 8.47
Por otro lado, en la tabla de variables categóricas se observa que la mayoría de las personas tiene acceso a internet y vive en zonas urbanas, algo importante porque actualmente muchos servicios financieros funcionan de manera digital. También se puede ver que predominan los niveles educativos intermedios y que la distribución entre hombres y mujeres es bastante equilibrada. Todo esto ayuda a tener una muestra más diversa y útil para analizar la inclusión financiera en Colombia.


3.3 Capacidad Adquisitiva e inclusión

Minusculas <- Base_de_datos_Taller_2 %>% 
  mutate(Cuenta_ahorros = recode(Cuenta_ahorros,
                                 "NO" = "No", 
                                 "SÍ" = "Sí")) %>%
  mutate(Genero = factor(Genero))

Minusculas <- Minusculas %>%
  mutate(Genero = fct_recode(Genero, 
                             "Masculino" = "0", 
                             "Femenino" = "1"))


Distrib_Ingr_prom <- ggplot(Minusculas, aes(x = Cuenta_ahorros, 
                                            y = Ingreso_promedio, 
                                            color = Cuenta_ahorros)) +
  geom_boxplot() +
  stat_summary(fun = mean, geom = "point",
               shape = 8, size = 2.5, color = "#6384CA") +
  
  scale_y_continuous(labels = dollar_format(prefix = "$ ")) +
  scale_color_manual(values = c("#A7BFC7","#2A5674")) +
  
  labs(
    title = "El ingreso como primer diferenciador",
    subtitle = "Ingreso promedio según tenencia de cuenta de ahorros",
    x = NULL,
    y = NULL) +
  
  theme_minimal(base_family = "segoe") +
  theme(plot.title = element_text(size = 35, color = "gray21", family = "segoe_b", 
                                  hjust = 0),
        plot.title.position = "plot",
        
        plot.subtitle = element_text(size = 28, color = "gray40", family = "segoe", 
                                     hjust = 0, margin = margin(b = 10)),
        plot.subtitle.position = "plot",
        axis.text.x = element_text(size = 25, color = "gray21"),
        axis.text.y = element_text(size = 25, color = "gray21"),
        panel.grid.major.x = element_blank(),
        panel.grid.major.y = element_line(linewidth = .2, linetype = "dashed"),
        panel.grid.minor = element_blank(),
        legend.position = "none",
        legend.text = element_blank(),
        legend.title = element_blank(),
        plot.margin = margin(15, 20, 10, 10))
Distrib_Ingr_prom

En general, ambos aspectos muestran una distribución sesgada positivamente, implicando la existencia de individuos con altos niveles de ingresos, independiente de la tenencia o no de cuenta de ahorros.

En el caso de los que no tienen cuenta, esto representa a personas que operan en la informalidad o eligen otros métodos de ahorro (meter el dinero debajo de la cama, por ejemplo). El hecho de que esto ocurra de manera más frecuente en la distribución de los individuos que no poseen cuenta de ahorros sugiere la idea de que, percibir altos ingresos no garantiza poseer obligatoriamente una cuenta bancaria.

Pese a lo anterior, las disparidades entre los que tienen o no cuenta de ahorros son claras. La distribución de las personas que si poseen cuenta muestran un rango notablemente mas amplio y con niveles superiores al millón de pesos, concentrándose en su mayoría entre el millón y medio y los dos millones y medio de pesos. En contraste, están los que no poseen cuenta de ahorros, cuentan con un rango más reducido y con niveles más bajos de ingresos: la mayoría no supera el millón de pesos.

El nivel de ingresos actúa entonces, como un obstáculo o un facilitador para la inclusión financiera. A medida que los ingresos aumentan, es más probable que una persona acceda a una cuenta de ahorro.


3.4 Perfil sociodemográfico

Rango_edad_genero <- Minusculas %>%
  select(Cuenta_ahorros, Edad, Genero) %>%
  mutate(Edad_rango = cut(Edad, breaks = seq(18, 73, by = 5), right = FALSE)) %>%
  group_by(Edad_rango, Genero, Cuenta_ahorros) %>%
  summarise(n = n(), .groups = "drop") %>%
  group_by(Edad_rango, Genero) %>%
  mutate(Edad_rango_porcentaje = n / sum(n) * 100)

Rango_edad_genero <- Rango_edad_genero %>%
  filter(Cuenta_ahorros == "Sí") %>%
  mutate(Edad_rango_porcentaje = ifelse(Genero == "Masculino",
                                        -Edad_rango_porcentaje, Edad_rango_porcentaje),
         n = ifelse(Genero == "Masculino", -n, n))


Distrib_Edad <- ggplot(Rango_edad_genero, aes(x = Edad_rango, y = Edad_rango_porcentaje,
                                              fill = Genero)) +
  geom_col() +
  coord_flip() +
  geom_richtext(aes(label = paste0(abs(round(Edad_rango_porcentaje, 1)), "%"),), 
                color = ifelse(Rango_edad_genero$Genero == "Masculino", "#FFFFFF", "#545AA6"),
                fill = NA, label.color = NA, hjust = -0, size = 8.5, show.legend = FALSE,
                family = "segoe",
                vjust = 0.5) +
  
  scale_y_continuous(labels = function(x) paste0(abs(x), "%"),
                     expand = c(0.1, 0.1)) +
  
  scale_fill_manual(values = c("Masculino" = "#23304A", "Femenino" = "#545AA6")) +
  
  labs(
    title = 'Los 30s: la nueva cara de la "inclusión"',
    subtitle = "Comparativa en la tenencia de cuenta según rango de edad y género.",
    x = NULL,
    y = NULL) +
  
  theme_minimal(base_family = "segoe") +
  theme(
    plot.title = element_text(size = 35, color = "gray21", family = "segoe_b", 
                              hjust = 0),
    plot.title.position = "plot",
    
    plot.subtitle = element_text(size = 28, color = "gray40", family = "segoe", 
                                 hjust = 0, margin = margin(b = 15)),
    plot.subtitle.position = "plot",
    plot.margin = margin(rep(15, 4)),
    
    axis.title.y = element_blank(),
    axis.text.y = element_markdown(size = 24, color = "gray21", hjust = 1),
    axis.title.x = element_blank(),
    axis.text.x = element_blank(),
    legend.position = "bottom",
    legend.text = element_text(size = 18, color = "gray21"),
    legend.title = element_blank(),
    
    
    panel.grid.major.x = element_blank(),
    panel.grid.minor.x = element_blank(),
    panel.grid.major.y = element_line(linewidth = .2, linetype = "dashed"),
    panel.grid.minor.y = element_blank())
Distrib_Edad

Este gráfico señala como la inclusión financiera se encuentra fuertemente marcada por factores poblacionales como la edad y el género. En primer lugar, se observa un patrón consistente en ambos géneros: a medida que la persona crece, la inclusión financiera también asciende, alcanzando su pico en el rango de los 33 y 38 años. Esto hecho puede deberse a que los 30s son una época en donde se comienza a pensar en metas financieras que podrían asegurar un futuro próspero (GBM Academy, 2023): independizarse, viajar, estudiar una maestría…

A partir de ese rango, desciende progresivamente. En el caso de las mujeres, la tasa más baja de inclusión se encuentra entre los 68 y 73 años, mientras que en los hombres se encuentra entre los 53 y 58 años: los adultos y adultos mayores enfrentan desafíos significativos en cuanto a inclusión, posiblemente por factores asociados al desconocimiento financiero y/o tecnológico.

Esto sugiere entonces, que el nivel de inclusión se encuentra asociado al ciclo de vida productivo, aunque no crece linealmente con la edad.

De la misma manera y pese a que ambos géneros alcanzan su nivel más alto de inclusión en el mismo rango, las mujeres solo logran un 38,5%, mientras que los hombres un 66,7%. El género masculino lidera la inclusión mientras que el femenino queda rezagado: un patrón que se observa en todos los rangos.

Es más probable que un hombre que se encuentre entre los 63 y 68 años tenga una cuenta de ahorros, que una mujer que se encuentra entre los 33 y 38 años. Esto refleja una brecha de género persistente en el acceso a cuentas de ahorro.


Educacion_Ahorro <- Minusculas %>%
  select(Nivel_educativo, Cuenta_ahorros) %>%
  group_by(Nivel_educativo, Cuenta_ahorros) %>%
  summarise(n = n(), .groups = "drop") %>%
  group_by(Nivel_educativo) %>%
  mutate(Educacion_porcentaje = n / sum(n) * 100)
View(Educacion_Ahorro)

Educacion_Ahorro <- Educacion_Ahorro %>% 
  mutate(Nivel_educativo = recode(Nivel_educativo,
                                 "0" = "Ninguna", 
                                 "1" = "Primaria",
                                 "2" = "Secundaria", 
                                 "3" = "Técnico",
                                 "4" = "Tecnología", 
                                 "5" = "Pregrado",
                                 "6" = "Posgrado")) %>%
  
  mutate(Nivel_educativo = factor(Nivel_educativo)) %>%
  mutate(Nivel_educativo = fct_relevel(Nivel_educativo, 
                                       "Ninguna", "Primaria", "Secundaria", "Técnico",
                                       "Tecnología", "Pregrado","Posgrado"))

Educacion <- ggplot(Educacion_Ahorro, aes(x = Nivel_educativo,
                                          y = Educacion_porcentaje, 
                                          fill = Cuenta_ahorros)) +
  geom_col(width = 0.7) +
  coord_flip() +
  
  geom_richtext(aes(label = paste0(round(Educacion_porcentaje, 1), "%"),
                    group = Cuenta_ahorros), 
                position = position_stack(vjust = 0.5),
                color = "#FFFFFF",
                fill = NA, label.color = NA, size = 8.5, show.legend = FALSE,
                family = "segoe") +
  
  scale_fill_manual(values = c("#A7BFC7","#2A5674")) +
  scale_y_continuous(labels = function(x) paste0(x, "%")) +
  
  labs(
    title = "A mayor formación, mayor inclusión",
    subtitle = "Impacto del nivel educativo en la inclusión financiera",
    x = NULL,
    y = NULL) +
  
  theme_minimal(base_family = "segoe") +
  theme(
    plot.title = element_text(size = 35, color = "gray21", family = "segoe_b", 
                              hjust = 0),
    plot.title.position = "plot",
    
    plot.subtitle = element_text(size = 28, color = "gray40", family = "segoe", 
                                 hjust = 0, margin = margin(b = 15)),
    plot.subtitle.position = "plot",
    plot.margin = margin(rep(15, 4)),
    
    axis.title.y = element_blank(),
    axis.text.y = element_markdown(size = 24, color = "gray21", hjust = 1),
    axis.title.x = element_blank(),
    axis.text.x = element_blank(),
    
    panel.grid.major.x = element_blank(),
    panel.grid.minor.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "bottom",
    legend.text = element_text(size = 18, color = "gray21"),
    legend.title = element_blank())
    
Educacion

Este gráfico ilustra la correlación directa entre el nivel educativo y la inclusión financiera. En los niveles de escolaridad básica predomina una brecha significativa de exclusión: las tasas de tenencia de cuenta de ahorro no superan el 20%. Esto puede deberse a que esta falta de formación académica implica barreras de acceso como la baja educación financiera o el empleo informal.

A medida que aumenta el nivel educativo también se observa un incremento sostenido en la proporción de personas con cuenta de ahorros. El mayor punto de inflexión se encuentra entre los niveles de secundaria y técnico con una diferencia de 20.7 puntos porcentuales, lo que sugiere que incluso en niveles técnicos de formación, las intervenciones en finanzas básicas resultan fundamentales para mejorar las tasas de inclusión.

Todo esto evidencia que la educación no solo influye en las oportunidades laborales sino también en la inclusión financiera.


3.5 Infraestructura, conectividad y territorio

datos_internet <- Minusculas %>%
  count(Acceso_internet, Cuenta_ahorros)

Incl_digital <- ggplot(datos_internet,
                       aes(x = factor(Acceso_internet), 
                           y = n,
                           fill = Cuenta_ahorros)) +
  
  geom_col(position = "dodge") +
  
  geom_text(aes(label = n),
            position = position_dodge(width = 0.9),
            vjust = -0.2,
            size = 8.5,
            family = "segoe",
            color = c("#A7BFC7","#2A5674", "#A7BFC7","#2A5674")) +
  
  labs(
    title = "Brecha digital e inclusión financiera ",
    subtitle = "Tenencia de cuenta quiénes entre tienen y no tienen acceso a internet", 
    x = "Acceso a internet",
    y = NULL) + 
  
  scale_x_discrete(labels = c("0" = "No", "1" = "Sí")) +
  scale_y_continuous(limits = c(0, 1200)) +
  scale_fill_manual(values = c("#A7BFC7","#2A5674")) +
  
  theme_minimal(base_family = "segoe") +
  theme(
    plot.title = element_text(size = 35, color = "gray21", family = "segoe_b", 
                              hjust = 0),
    plot.title.position = "plot",
    
    plot.subtitle = element_text(size = 28, color = "gray40", family = "segoe", 
                                 hjust = 0, margin = margin(b = 18)),
    plot.subtitle.position = "plot",
    
    axis.title.y = element_blank(),
    axis.text.y = element_markdown(size = 24, color = "gray40", hjust = 1),
    axis.title.x = element_markdown(size = 24, color = "gray21"),
    axis.text.x = element_markdown(size = 24, color = "gray21", hjust = 1),
    
    panel.grid.major.x = element_blank(),
    panel.grid.minor.x = element_blank(),
    panel.grid.major.y = element_line(linewidth = .2, linetype = "dashed"),
    panel.grid.minor.y = element_blank(),
    legend.position = "right",
    legend.text = element_text(size = 18, color = "gray21"),
    legend.title = element_blank())

Incl_digital

Posteriormente, se examina la distribución de la variable acceso a internet según la tenencia de cuenta de ahorros, con el fin de identificar posibles diferencias entre ambos grupos.

El gráfico evidencia una asociación entre el acceso a internet y la tenencia de cuenta de ahorros. Se observa que, entre las personas que no cuentan con acceso a internet, predomina la población sin cuenta de ahorros (1183 casos), mientras que una proporción considerablemente menor sí posee este producto financiero (283 casos). En contraste, dentro del grupo con acceso a internet, aumenta significativamente la cantidad de personas con cuenta de ahorros (1487 casos).

Estos resultados sugieren que el acceso a internet podría estar relacionado con un mayor nivel de inclusión financiera, debido a que facilita el acceso a servicios bancarios digitales, consultas en línea y herramientas tecnológicas asociadas al sistema financiero.
datos <- Minusculas %>%
  mutate(
    Zona = case_when(
      Zona_Ciudad == 1 ~ "Ciudad",
      Zona_Intermedia == 1 ~ "Intermedia",
      Zona_Rural == 1 ~ "Rural",
      Zona_Rural_disperso == 1 ~ "Rural disperso")) %>%
  count(Zona, Cuenta_ahorros)

Zonas <- ggplot(datos, aes(x = Zona, y = n, fill = Cuenta_ahorros)) +
  geom_col(position = "dodge") +
  geom_text(
    aes(label = n),
    position = position_dodge(width = 0.9),
    vjust = -0.2,
    size = 8.5,
    family = "segoe",
    color = c("#A7BFC7","#2A5674", "#A7BFC7","#2A5674", "#A7BFC7","#2A5674", "#A7BFC7","#2A5674")) +
  
  labs(
    title = "Diferentes realidades, un mismo producto financiero",
    subtitle = "Comparación de la tenencia de cuenta entre zonas geográficas",
    x = NULL,
    y = NULL) +
  
  scale_fill_manual(values = c("#A7BFC7","#2A5674")) +
  
  theme_minimal(base_family = "segoe") +
  theme_minimal(base_family = "segoe") +
  theme(
    plot.title = element_text(size = 35, color = "gray21", family = "segoe_b", 
                              hjust = 0),
    plot.title.position = "plot",
    
    plot.subtitle = element_text(size = 28, color = "gray40", family = "segoe", 
                                 hjust = 0, margin = margin(b = 18)),
    plot.subtitle.position = "plot",
    
    axis.title.y = element_blank(),
    axis.text.y = element_markdown(size = 24, color = "gray40", hjust = 1),
    axis.title.x = element_blank(),
    axis.text.x = element_markdown(size = 24, color = "gray21", hjust = 1),
    
    panel.grid.major.x = element_blank(),
    panel.grid.minor.x = element_blank(),
    panel.grid.major.y = element_line(linewidth = .2, linetype = "dashed"),
    panel.grid.minor.y = element_blank(),
    legend.position = "right",
    legend.text = element_text(size = 18, color = "gray21"),
    legend.title = element_blank())
Zonas

Por último, se analiza la distribución de la tenencia de cuenta de ahorros según la zona de residencia, con el propósito de identificar posibles diferencias territoriales en el acceso a servicios financieros.

El gráfico muestra que la mayor concentración de personas en ambos aspectos, se encuentra en la zona urbana (Ciudad), lo cual puede estar asociado a una mayor densidad poblacional y un mayor acceso a servicios financieros en estas áreas. Asimismo, se observa que en todas las zonas predomina la población que no posee cuenta de ahorros, aunque la diferencia es más marcada en las zonas intermedia, rural y rural dispersa.

En particular, las zonas rurales y rurales dispersas presentan menores frecuencias de personas con cuenta de ahorros, lo que podría reflejar limitaciones en el acceso a entidades financieras, infraestructura tecnológica o servicios bancarios. En general, los resultados sugieren la existencia de diferencias territoriales relacionadas con la inclusión financiera.

4 Modelado

4.1 Algoritmo de regresión logística

4.1.1 Preparación de la variable dependiente

En primer lugar, se construyó la variable dependiente binaria asociada a la tenencia de cuenta de ahorros. Se asignó el valor de 1 a las personas que poseen cuenta de ahorros y 0 a quienes no poseen este producto financiero. Una vez preparada la información, se procedió al entrenamiento del modelo de regresión logística binaria.
Base_normalizada2 <- Base_de_datos_Taller_2 %>% 
  mutate_at(c("Cuenta_ahorros"), ~as.factor(.)) %>%
  select(-c(Ingreso_promedio, Nivel_educativo, Edad, Zona_Ciudad)) %>%
  na.omit()

Base_normalizada2 <- Base_normalizada2 %>%
  mutate(
    cuenta_ahorros = ifelse(Cuenta_ahorros == "SÍ", 1, 0),
    cuenta_ahorros_f = factor(
      cuenta_ahorros,
      levels = c(0, 1),
      labels = c("No", "Si")))



datos_modelo <- Base_normalizada2 %>%
 select(
   cuenta_ahorros,
   cuenta_ahorros_f,
   Ingreso_promedioz,
   Edadz,
   Nivel_educativoz,
   Genero,
   Acceso_internet,
   Zona_Intermedia,
   Zona_Rural,
   Zona_Rural_disperso) %>%
 na.omit()

Las variables incluidas fueron:

  • Ingreso promedio normalizado
  • Edad normalizada
  • Nivel educativo normalizado
  • Género
  • Acceso a internet
  • Zona geográfica
En el caso de la variable zona geográfica, se dejó la subvariable ciudad como referencia para comparar el efecto de las demás zonas respecto al área urbana.

4.1.2 División de datos y entrenamiento

Como se menciono anteriormente, la base de datos se divide en un conjunto de entrenamiento y otro de prueba, utilizando el 70% de las observaciones para entrenar el modelo y el 30% restante para evaluar su desempeño predictivo.
set.seed(23)

idx <- createDataPartition(y = datos_modelo$cuenta_ahorros_f, p = 0.70, 
                           list = FALSE)
train <- datos_modelo[idx, ]
test  <- datos_modelo[-idx, ]

Una vez preparada la información, se procedió al entrenamiento del modelo de regresión logística binaria.

fit_logit <- glm(
 cuenta_ahorros ~ Ingreso_promedioz + Edadz +
   Nivel_educativoz + Genero +
   Acceso_internet +
   Zona_Intermedia + Zona_Rural +
   Zona_Rural_disperso,
 data = train,
 family = binomial())

4.1.3 Resultados

4.1.3.1 Resultados iniciales

Coeficientes_logit<- summary(fit_logit)$coefficients
Coeficientes_logit[ , "Estimate"] <- round(Coeficientes_logit[ , "Estimate"], 1)
Coeficientes_logit[ , "Std. Error"] <- round(Coeficientes_logit[ , "Std. Error"], 1)
Coeficientes_logit[ , "z value"] <- round(Coeficientes_logit[ , "z value"], 2)
Coeficientes_logit[ , 'Pr(>|z|)'] <- round(Coeficientes_logit[ , 'Pr(>|z|)'], 5)

rownames(Coeficientes_logit) <- c("Intercepto", "Ingreso promedio", "Edad", "Nivel educativo", "Género", "Acceso a internet", "Zona intermedio", "Zona rural", "Zona rural disperso")

colnames(Coeficientes_logit) <- c("Estimación", "Error estándar", "Valor z", "Pr(>|z|)")


kable(Coeficientes_logit, 
      digits = 5, 
      caption = "",
      align = c('l','c', 'c', 'c', 'c'),
      format = "html") %>%
  
  kable_styling(full_width = FALSE, html_font = "Segoe UI", position = "left",
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, color = "#3C4967", bold = TRUE) %>%
  row_spec(1:9, color = "#295675") %>%
  
  column_spec(1, width = "18em") %>%
  column_spec(2:4, width = "7em")
Estimación Error estándar Valor z Pr(>|z|)
Intercepto -2.0 0.2 -10.74 0.00000
Ingreso promedio 2.2 0.3 8.12 0.00000
Edad -0.2 0.2 -0.77 0.44388
Nivel educativo 2.8 0.3 10.25 0.00000
Género -0.6 0.1 -5.72 0.00000
Acceso a internet 0.6 0.1 5.26 0.00000
Zona intermedio -0.2 0.1 -1.12 0.26458
Zona rural 0.0 0.2 -0.29 0.77142
Zona rural disperso 0.1 0.2 0.28 0.78059

Los resultados del modelo Logit muestran que las variables ingreso promedio normalizado, nivel educativo normalizado, género y acceso a internet presentan efectos estadísticamente significativos sobre la probabilidad de poseer una cuenta de ahorros, debido a que sus valores p fueron inferiores a 0.05.

El ingreso promedio normalizado presentó un coeficiente positivo de 2.19449, indicando que mayores niveles de ingreso incrementan significativamente la probabilidad de poseer cuenta de ahorros. Asimismo, el nivel educativo normalizado obtuvo un coeficiente positivo de 2.75306, siendo una de las variables más importantes dentro del modelo.

Por su parte, el acceso a internet presentó un coeficiente positivo de 0.63948, sugiriendo que las personas con acceso a internet tienen mayores probabilidades de acceder a servicios financieros formales. En contraste, la variable género presentó un coeficiente negativo de -0.58901, evidenciando diferencias entre las categorías utilizadas en la codificación de esta variable.

Las variables edad y zona geográfica no resultaron estadísticamente significativas, debido a que sus valores p fueron superiores a 0.05. Esto indica que, controlando las demás variables, no aportan evidencia suficiente para explicar diferencias importantes en la tenencia de cuenta de ahorros. Adicionalmente, la deviance residual disminuyó de 2826.6 a 2306.4 respecto a la deviance nula, indicando que las variables incluidas aportan capacidad explicativa al modelo. El valor AIC obtenido fue de 2324.4.


4.1.3.2 Interpretación de los Odds Ratio

odds_ratios <- as.data.frame(exp(coef(fit_logit)))

rownames(odds_ratios) <- c("Intercepto", "Ingreso promedio", "Edad", "Nivel educativo", "Género", "Acceso a internet", "Zona intermedio", "Zona rural", "Zona rural disperso")
colnames(odds_ratios) <- c("Valor")


kable(odds_ratios, 
      digits = 2, 
      caption = "Odds Ratios",
      align = c('l','c'),
      format = "html") %>%
  
  kable_styling(full_width = FALSE, html_font = "Segoe UI", position = "left",
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, color = "#3C4967", bold = TRUE) %>%
  row_spec(1:9, color = "#295675") 
Odds Ratios
Valor
Intercepto 0.13
Ingreso promedio 8.98
Edad 0.86
Nivel educativo 15.69
Género 0.55
Acceso a internet 1.90
Zona intermedio 0.85
Zona rural 0.96
Zona rural disperso 1.05

El nivel educativo normalizado presentó el efecto más fuerte dentro del modelo, con un odds ratio de 15.69, indicando que incrementos en el nivel educativo aumentan considerablemente las probabilidades relativas de poseer cuenta de ahorros.

Asimismo, el ingreso promedio normalizado obtuvo un odds ratio de 8.98 y el acceso a internet presentó un odds ratio de 1.90: las personas con acceso digital o las que tienen niveles de ingresos altos tienen mayores probabilidades de estar incluidos financieramente.

Por otro lado, la variable género presentó un odds ratio de 0.55, indicando una disminución relativa en la probabilidad de poseer cuenta de ahorros para la categoría codificada como 1 respecto a la categoría de referencia.

Las variables asociadas a la zona geográfica presentaron odds ratio cercanos a 1, indicando un efecto reducido sobre la probabilidad de poseer cuenta de ahorros respecto a la subvariable de referencia ciudad.


4.1.3.3 Matriz de confusión y metricas

p_hat <- predict(
 fit_logit,
 newdata = test,
 type = "response")

pred_clase <- factor(
 ifelse(p_hat >= 0.5, "Si", "No"),
 levels = c("No", "Si"))


Cm_logit <- data.frame(
  NO = c(468, 176),
= c(72, 184), 
  row.names = c("NO", "SÍ"))

kable(Cm_logit, 
      caption = "Matriz de confusión",
      align = c('c','c'),
      format = "html") %>%
  
  kable_styling(full_width = FALSE, html_font = "Segoe UI", position = "left",
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, color = "#3C4967", bold = TRUE) %>%
  row_spec(1:2, color = "#295675")
Matriz de confusión
NO
NO 468 72
176 184
Metricas_logit <- data.frame(
  Metrica = c(
    "Exactitud", 
    "Intervalo de Confianza (95%)", 
    "Tasa de no informacion", 
    "Índice Kappa", 
    "Sensibilidad", 
    "Especificidad", 
    "Valor Predictivo Positivo", 
    "Valor Predictivo Negativo",
    "Exactitud balanceada"),
  Valor = c(
    0.7244, 
    "(0.694, 0.7534)", 
    0.6, 
    0.3969, 
    0.5111, 
    0.8667, 
    0.7188, 
    0.7267, 
    0.6889))

kable(Metricas_logit, 
      caption = "Métricas de desempeño",
      align = c('l','c', 'c', 'c', 'c'),
      format = "html") %>%
  
  kable_styling(full_width = FALSE, html_font = "Segoe UI", position = "left",
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, color = "#3C4967", bold = TRUE) %>%
  row_spec(1:9, color = "#295675")
Métricas de desempeño
Metrica Valor
Exactitud 0.7244
Intervalo de Confianza (95%) (0.694, 0.7534)
Tasa de no informacion 0.6
Índice Kappa 0.3969
Sensibilidad 0.5111
Especificidad 0.8667
Valor Predictivo Positivo 0.7188
Valor Predictivo Negativo 0.7267
Exactitud balanceada 0.6889

La matriz de confusión mostró una exactitud (Accuracy) de 72.44%, superior al No Information Rate de 60%, indicando que el modelo clasifica mejor que una predicción basada únicamente en la categoría mayoritaria.

Asimismo, el modelo presentó una especificidad de 86.67%, evidenciando una buena capacidad para identificar correctamente a las personas que no poseen cuenta de ahorros. La sensibilidad obtenida fue de 51.11%, indicando una capacidad moderada para detectar correctamente a las personas que sí poseen cuenta de ahorros.

El valor de Kappa fue de 0.3969, representando un nivel de concordancia moderado entre las clasificaciones realizadas por el modelo y los valores reales observados. Además, el Balanced Accuracy fue de 68.89%, reflejando un desempeño relativamente equilibrado entre ambas categorías.


4.1.3.4 Curvas ROC y AUC

roc_logit <- roc(
 response = test$cuenta_ahorros_f,
 predictor = p_hat,
 levels = c("No", "Si"))

auc_val <- auc(roc_logit)

auc_val
## Area under the curve: 0.771
plot(
 roc_logit,
 main = sprintf("ROC Logit | AUC = %.3f", auc_val))

La curva ROC permite evaluar la capacidad discriminante del modelo de clasificación. El modelo Logit obtuvo un área bajo la curva (AUC) de 0.771, valor que indica una capacidad de clasificación aceptable y superior al azar.

La forma de la curva muestra que el modelo logra distinguir de manera relativamente adecuada entre personas con y sin cuenta de ahorros, respaldando la utilidad predictiva de las variables seleccionadas.

Posteriormente, se calculó un umbral óptimo de clasificación mediante el criterio de Youden, buscando un mejor equilibrio entre sensibilidad y especificidad.


4.1.3.5 Umbral óptimo

thr <- pROC::coords(
 roc_logit,
 x = "best",
 best.method = "youden",
 ret = "threshold")

umbral <- as.numeric(thr)
El umbral óptimo calculado mediante el criterio de Youden fue de 0.3492. Esto indica que el mejor punto de corte para clasificar observaciones no corresponde al valor tradicional de 0.5, sino a una probabilidad menor, sugiriendo que el modelo puede mejorar la detección de personas con cuenta de ahorros utilizando un criterio de clasificación menos restrictivo.


4.1.3.6 Resultados finales

pred_clase_opt <- factor(
  ifelse(p_hat >= umbral, "Si", "No"),
  levels = c("No", "Si"))


resultados_logit <- data.frame(
 Real = test$cuenta_ahorros_f,
 Probabilidad_Si = p_hat,
 Prediccion_05 = pred_clase,
 Prediccion_umbral_optimo = pred_clase_opt)

colnames(resultados_logit) <- c("Valor real", "Probabilidad: Sí", "Pred. inicial", "Pred. umbral óptimo")

kable(head(resultados_logit), 
      caption = "Resultados",
      align = c('l','c', 'c', 'c', 'c'),
      format = "html") %>%
  
  kable_styling(full_width = FALSE, html_font = "Segoe UI", position = "left",
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, color = "#3C4967", bold = TRUE) %>%
  row_spec(1:6, color = "#295675")
Resultados
Valor real Probabilidad: Sí Pred. inicial Pred. umbral óptimo
No 0.1581716 No No
Si 0.3984861 No Si
Si 0.5456241 Si Si
No 0.4292172 No Si
Si 0.1812070 No No
No 0.2782624 No No

Finalmente, se construyó una tabla con las probabilidades estimadas y las clasificaciones generadas por el modelo.

La tabla de resultados finales permite comparar los valores reales con las probabilidades estimadas y las clasificaciones realizadas mediante el umbral tradicional de 0.5 y el umbral óptimo calculado con la curva ROC.

Se observa que el modelo asigna probabilidades altas a muchos casos pertenecientes a la categoría “Sí” y probabilidades bajas a numerosos casos de la categoría “No”, evidenciando una adecuada capacidad de discriminación entre ambas categorías. No obstante, algunos errores de clasificación aparecen en observaciones con probabilidades cercanas al punto de corte, especialmente entre 0.30 y 0.45. Asimismo, el uso del umbral óptimo permite detectar un mayor número de casos positivos respecto al umbral tradicional, aunque esto también puede generar algunos falsos positivos adicionales. En general, los resultados son coherentes con las métricas obtenidas previamente en la matriz de confusión y la curva ROC, confirmando que el modelo presenta una capacidad predictiva aceptable para clasificar la tenencia de cuenta de ahorros.


4.2 Algoritmo del K-vecino más cercano

4.2.1 Preparación de variables

Base_normalizada <-  Base_de_datos_Taller_2 %>% 
  mutate(
    Cuenta_ahorros = factor(Cuenta_ahorros, levels = c("NO", "SÍ"))) %>%
  select(
    Cuenta_ahorros,
    Ingreso_promedioz,
    Edadz,
    Nivel_educativoz,
    Genero,
    Acceso_internet,
    Zona_Intermedia,
    Zona_Rural,
    Zona_Rural_disperso) %>%
  na.omit()

View(Base_normalizada)

Para la construcción del modelo se utilizaron las variables previamente transformadas. En el caso de la zona geográfica, se dejó la subvariable ciudad como referencia.


4.2.2 Selección del mejor valor de k

set.seed(23)

Index_Entrenamiento <- createDataPartition(
  y = Base_normalizada$Cuenta_ahorros,
  p = 0.70,
  list = FALSE)

Entrenamiento <- Base_normalizada[Index_Entrenamiento, ]
Testeo <- Base_normalizada[-Index_Entrenamiento, ]



Entrenamiento$Cuenta_ahorros <- factor(
  Entrenamiento$Cuenta_ahorros,
  levels = c("NO", "SÍ"))

Testeo$Cuenta_ahorros <- factor(
  Testeo$Cuenta_ahorros,
  levels = c("NO", "SÍ"))



kgrid <- expand.grid(k = seq(1, 10))


set.seed(23)

Modelo_knn <- train(
  Cuenta_ahorros ~ ., 
  data = Entrenamiento, 
  method = "knn",
  metric = "Kappa",
  preProcess = c("center", "scale"),
  trControl = trainControl(
    method = "repeatedcv",
    number = 10,
    sampling = "down",
    classProbs = TRUE),
  tuneGrid = kgrid)

plot(Modelo_knn)

Prediccion_knn <- predict(
  Modelo_knn,
  newdata = Testeo)

Probabilidad_knn <- predict(
  Modelo_knn,
  newdata = Testeo,
  type = "prob")
Con el fin de identificar el número óptimo de vecinos más cercanos, se evaluaron diferentes valores de K mediante validación cruzada, utilizando la métrica Kappa, buscando un equilibrio adecuado entre capacidad predictiva y estabilidad del modelo. El mejor desempeño del modelo se obtuvo utilizando un valor de k = 9.


4.2.3 Resultados

Cm_knn <- data.frame(
  NO = c(388, 152),
= c(117, 243), 
  row.names = c("NO", "SÍ"))

kable(Cm_knn, 
      caption = "Matriz de confusión",
      align = c('c','c'),
      format = "html") %>%
  
  kable_styling(full_width = FALSE, html_font = "Segoe UI", position = "left",
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, color = "#3C4967", bold = TRUE) %>%
  row_spec(1:2, color = "#295675")
Matriz de confusión
NO
NO 388 117
152 243
Metricas_knn <- data.frame(
  Metrica = c(
    "Exactitud", 
    "Intervalo de Confianza (95%)", 
    "Tasa de no informacion", 
    "Índice Kappa", 
    "Sensibilidad", 
    "Especificidad", 
    "Valor Predictivo Positivo", 
    "Valor Predictivo Negativo",
    "Exactitud balanceada"),
  Valor = c(
    0.7011, 
    "(0.67, 0.73)", 
    0.6, 
    0.3872, 
    0.675, 
    0.7185, 
    0.7188, 
    0.7683, 
    0.6968))

kable(Metricas_knn, 
      caption = "Métricas de desempeño",
      align = c('l','c', 'c', 'c', 'c'),
      format = "html") %>%
  
  kable_styling(full_width = FALSE, html_font = "Segoe UI", position = "left",
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, color = "#3C4967", bold = TRUE) %>%
  row_spec(1:9, color = "#295675")
Métricas de desempeño
Metrica Valor
Exactitud 0.7011
Intervalo de Confianza (95%) (0.67, 0.73)
Tasa de no informacion 0.6
Índice Kappa 0.3872
Sensibilidad 0.675
Especificidad 0.7185
Valor Predictivo Positivo 0.7188
Valor Predictivo Negativo 0.7683
Exactitud balanceada 0.6968

Posteriormente, se evaluó el desempeño predictivo del modelo utilizando el conjunto de prueba. La matriz de confusión mostró una exactitud de 68.11%, superior al No Information Rate de 60%, indicando que el modelo clasifica mejor que una predicción basada únicamente en la categoría mayoritaria o por azar.

Asimismo, el modelo presentó una sensibilidad de 67.50%, evidenciando una buena capacidad para detectar correctamente a las personas que sí poseen cuenta de ahorros. La especificidad obtenida fue de 68.52%, mostrando un desempeño relativamente equilibrado en la identificación de ambas categorías.

El valor de Kappa fue de 0.3516, indicando un nivel de concordancia moderado entre las clasificaciones realizadas por el modelo y los valores reales observados. De igual manera, la exactitud balanceada fue de 68.01%, reflejando un comportamiento relativamente balanceado entre sensibilidad y especificidad.


4.2.3.1 Curvas ROC y AUC

Prediccion_ROCR <- prediction(
  predictions = Probabilidad_knn$SÍ,
  labels = Testeo$Cuenta_ahorros)

Performance_ROC <- performance(
  Prediccion_ROCR,
  measure = "tpr",
  x.measure = "fpr")

plot(
  Performance_ROC,
  main = "Curva ROC - Modelo KNN",
  col = "blue",
  lwd = 2)

abline(a = 0, b = 1, lty = 2, col = "gray")

AUC_knn <- performance(
  Prediccion_ROCR,
  measure = "auc")

AUC_knn <- AUC_knn@y.values[[1]]

AUC_knn
## [1] 0.7460262

Además, y con el propósito de evaluar la capacidad discriminante del modelo, se construyó la curva ROC y se calculó el área bajo la curva (AUC).

El modelo KNN obtuvo un AUC de 0.7367, indicando una capacidad de clasificación aceptable y superior al azar. La curva ROC muestra que el modelo logra discriminar de manera razonable entre personas con y sin cuenta de ahorros, aunque su desempeño fue ligeramente inferior al obtenido por el modelo Logit.


4.2.3.2 Resultados finales

resultados_knn <- data.frame(
  Real = Testeo$Cuenta_ahorros,
  Probabilidad_Si = Probabilidad_knn$SÍ,
  Prediccion_KNN = Prediccion_knn)

colnames(resultados_knn) <- c("Valor real", "Probabilidad: Sí", "Pred")

kable(head(resultados_knn), 
      caption = "Métricas de desempeño",
      align = c('l','c', 'c', 'c', 'c'),
      format = "html") %>%
  
  kable_styling(full_width = FALSE, html_font = "Segoe UI", position = "left",
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(0, color = "#3C4967", bold = TRUE) %>%
  row_spec(1:6, color = "#295675")
Métricas de desempeño
Valor real Probabilidad: Sí Pred
NO 0.1111111 NO
0.5555556
0.8000000
NO 0.4444444 NO
0.3333333 NO
NO 0.6666667

La tabla de resultados permite comparar las probabilidades estimadas con las clasificaciones realizadas por el modelo KNN. Se observa que el modelo asigna probabilidades altas a numerosos casos pertenecientes a la categoría “SÍ” y probabilidades bajas a muchos casos de la categoría “NO”, evidenciando una adecuada capacidad de discriminación entre ambas categorías.

Sin embargo, también se identifican algunos errores de clasificación, especialmente en observaciones con probabilidades cercanas al punto de decisión. En general, los resultados obtenidos son coherentes con las métricas observadas en la matriz de confusión y la curva ROC, confirmando que el modelo presenta una capacidad predictiva aceptable para clasificar la tenencia de cuenta de ahorros.

5 Comparación entre ambos modelos

Con el fin de evaluar el desempeño de los modelos de clasificación implementados, se compararon las métricas obtenidas por el modelo de regresión logística (Logit) y el modelo del K-vecino más cercano

El modelo Logit presentó una exactitud, especificidad y un valor Kappa superior al del modelo kNN. Esto indica que, en términos generales, el modelo Logit logró clasificar correctamente una mayor proporción de observaciones dentro del conjunto de prueba, además de ser más eficiente evitando falsos positivos, clasificando correctamente a las personas que no poseen cuenta de ahorros y presentando, a su vez, una concordancia moderadamente mejor respecto a las clasificaciones reales observadas.

Por otro lado, el modelo KNN presentó un mejor desempeño en cuanto a sensibilidad, indicando que fue más efectivo identificando correctamente a las personas que poseen cuenta de ahorros.

Asimismo, ambos modelos superaron el No Information Rate de 60%, evidenciando que ambos poseen capacidad predictiva superior a una clasificación basada únicamente en la categoría mayoritaria. Lo mismo ocurre con la exactitud balanceada, en donde ambos modelos presentan un desempeño relativamente equilibrado considerando ambas categorías de clasificación.
roc_knn <- roc(
  response = Testeo$Cuenta_ahorros,
  predictor = Probabilidad_knn$SÍ,
  levels = c("NO", "SÍ"))

plot(
  roc_logit,
  col = "red",
  lwd = 2,
  main = "Comparación de Curvas ROC")

plot(
  roc_knn,
  add = TRUE,
  col = "blue",
  lwd = 2)

abline(a = 0, b = 1, lty = 2, col = "gray")

legend(
  "bottomright",
  legend = c(
    paste("Logit | AUC =", round(auc(roc_logit), 3)),
    paste("KNN | AUC =", round(auc(roc_knn), 3))),
  col = c("red", "blue"),
  lwd = 2,
  bty = "n")

Finalmente, para el área bajo la curva ROC (AUC), los valores obtenidos en ambos casos indican una capacidad de clasificación aceptable y superior al azar. Sin embargo, el modelo Logit presentó un mejor desempeño discriminante general, logrando separar de manera más adecuada las observaciones pertenecientes a cada categoría.

Considerando el conjunto de métricas obtenidas, el modelo Logit sería el más recomendable para este problema, debido a que presentó un mejor desempeño general, mayor capacidad discriminante y una interpretación más clara de las variables explicativas. Además, este modelo permite interpretar estadísticamente el efecto de cada variable mediante odds ratio, facilitando el análisis estadístico y económico en materia de inclusión financiera.

6 Conclusiones y recomendaciones

Al finalizar este trabajo, podemos confirmar que aún existen dificultades para la inclusión financiera en Colombia. esto se refleja en el hecho de que solo un 40% de la población encuestada posee cuenta de ahorros; por ende, el otro 60% permanece fuera del sistema bancario formal. Esto significa que, pese a los avances tecnológicos, aún hay brechas y barreras, ya sean de tipo económico, educativo y social.

También se observó que el ingreso promedio, el nivel educativo y el acceso a internet son factores decisivos para que las personas tengan una cuenta de ahorros. Estos resultados muestran que las personas que cuentan con mayores ingresos y una formación académica más altas tienen más posibilidades de estar incluidas en el sistema financiero, al tener una estabilidad económica; si se añade el poder acceder a una conexión digital, se presentan mayores probabilidades de tener cuenta de ahorros. Esto facilita aún más el acceso a estos servicios.

Por otro lado, las variables edad y zona de residencia no fueron muy relevantes en el modelo logit, pero sí mostraron varias diferencias importantes en el análisis descriptivo, donde en las zonas rurales y dispersas se observó cierta exclusión financiera y la inclusión financiera suele crecer hasta llegar a la edad adulta para luego comenzar a disminuir.

Ambos modelos demostraron tener una capacidad de predicción aceptable, pero el modelo logit nos permite una mayor exactitud y entender de mejor manera las variables explicativas.

No queda más que añadir, que, aunque el acceso a una cuenta ahorro es una condición necesaria, no es suficiente para lograr una verdadera inclusión financiera, se requiere además garantizar el uso efectivo de este y otros productos financieros (Cano, Esguerra, García, Rueda, & Velazco, 2014). “No se trata solo de que más ciudadanos tengan cuentas bancarias o acceso a medios digitales, sino de garantizar condiciones reales de participación en el sistema financiero. En palabras simples, que el crédito sea accesible, que el ahorro sea posible y que las herramientas de inversión no estén restringidas a unos pocos” (Facultad de Economía, Empresa y Desarrollo Sostenible - FEEDS, 2025).

7 Bibliografía

Banca de las Oportunidades . (s.f.). Encuestas de demanda. Obtenido de Banca de las Oportunidades : https://www.bancadelasoportunidades.gov.co/es/publicaciones/encuestas-de-demanda

BBVA. (31 de diciembre de 2024). Inclusión financiera: qué es y cómo puede reducir la pobreza. Obtenido de BBVA: https://www.bbva.com/es/sostenibilidad/que-es-la-inclusion-financiera/

Cano, C. G., Esguerra, M., García, N., Rueda, J. L., & Velazco, A. M. (2 de mayo de 2014). Inclusión financiera en Colombia. Obtenido de Banco de la República: https://www.banrep.gov.co/sites/default/files/eventos/archivos/sem_357.pdf

DAVIbank. (s.f.). Qué es una Cuenta de Ahorros - DAVIbank. Obtenido de DAVIbank: https://www.davibank.com/personas/cuentas-e-inversion/mas-informacion/definicion-cuenta-ahorro

Elastic. (s.f.). ¿Qué es kNN? Obtenido de Elastic: the Search AI Company: https://www.elastic.co/es/what-is/knn

Facultad de Economía, Empresa y Desarrollo Sostenible - FEEDS. (2 de septiembre de 2025). Inclusión financiera en Colombia: entre el reto del ahorro y el costo del crédito. Obtenido de Universidad de La Salle: https://lasalle.edu.co/es/noticias/inclusion-financiera-en-colombia-entre-el-reto-del-ahorro-y-el-costo-del-credito

GBM Academy. (28 de marzo de 2023). Metas financieras que deberias cumplir en los 30. Obtenido de GBM: https://gbm.com/media/the-academy/metas-financieras-que-deberias-cumplir-en-los-30/

Grupo Banco Mundial. (29 de marzo de 2022). Inclusión financiera. Obtenido de Banco Mundial: https://www.bancomundial.org/es/topic/financialinclusion/overview

iuvity. (s.f.). Regresión logística: ¿cuáles son sus claves en el área financiera? Obtenido de iuvity: https://www.iuvity.com/es/blog/regresion-logistica-cuales-son-sus-claves-en-el-area-financiera