1. Resumen Ejecutivo: Evolución de la Cartera de Créditos

Este conjunto de datos ofrece una visión detallada de la evolución de la cartera de créditos de las entidades financieras en Colombia, proporcionando datos clave sobre las diferentes modalidades de crédito, incluyendo crédito comercial, de consumo, microcrédito y de vivienda. Algunos temas importantes del conjunto de datos incluyen, para el corte de agosto 2023 vs agosto 2024:

Desglose por Modalidad de Crédito:

Indicadores de Riesgo y Mora:

Fuente: https://www.superfinanciera.gov.co/powerbi/reportes/510/542/

1.1 Visión Panorámica de los datos y Limpieza:

Se genera una limpieza basica en los datos, para un mejor manejo.

library(dplyr)
library(scales)
options(scipen=999)


CarteraDatos <- CarteraDatos %>%
  rename_all(~ gsub(" ", "", .)) %>%
  mutate(across(6:9, ~ as.numeric(.) / 1000000))%>%
  mutate(across(10:12, ~ as.numeric(sub(",", ".", gsub(" %", "", .))) / 100))

2. Tabla Dinámica en HTML:

Se presentan los primeros 20 registros por practicidad.

library(formattable)

CarteraDatos<-as.data.frame(CarteraDatos)
CarteraDatosv <- CarteraDatos %>% 
  slice(1:20)

##formattable(CarteraDatosv, list(
##  area(col = 6:9) ~ formatter("span",
  ##                            x ~ dollar(x, prefix = "$", big.mark = ",", digits = 2),
    ##                          style = ~ style(color = "Blue")),
##  area(col = 10:12) ~ formatter("span",
  ##                              x ~ paste0(formatC(x * 100, format = "f", digits = 1), "%"),
    ##                            style = ~ style(color = "Green"))
##))

library(dplyr)
library(DT)

# Crear la tabla interactiva
datatable(CarteraDatosv, 
          options = list(pageLength = 10, autoWidth = TRUE),
          rownames = FALSE) %>%
  # Formato de las columnas 6 a 9 en dólares con dos decimales
  formatCurrency(columns = 6:9, currency = "$", interval = 3, mark = ",", digits = 2) %>%
  # Formato de las columnas 10 a 12 en porcentaje con un decimal
  formatPercentage(columns = 10:12, digits = 1) %>%
  # Aplicar color de fondo dinámico a las columnas 6 a 9 si el valor es alto
  formatStyle(columns = 6:9,
              backgroundColor = styleInterval(100000, c("transparent", "rgba(255, 99, 71, 0.2)")),
              color = "blue") %>%
  # Aplicar color dinámico a las columnas 10 a 12 basado en el valor
  formatStyle(columns = 10:12,
              color = styleInterval(c(0.05, 0.1), c("red", "orange", "green")))

3. Filtro por Variable Categórica: 2024-08 vs 2023-08 en Modalidad Comercial

Se desea detallar la variacion del Promedio de Indicador de Mora y el Indicador de Riesgo en todas las entidades financieras; de agosto de 2024 versus el cierre de agosto del 2023 de la modalidad de credito comercial.

CarteraDatos_Corte <- CarteraDatos %>%
  filter(Modalidad == "Comercial") %>%  
  group_by(Fecha) %>%
  summarise(
    PromedioIndicadorMora = mean(Indicadormora, na.rm = TRUE),
    PromedioIndicadorRiesgo = mean(Indicadorriesgo, na.rm = TRUE)
  )


formattable(CarteraDatos_Corte, list(
  area(col = 2:3) ~ formatter("span",
                                x ~ paste0(formatC(x * 100, format = "f", digits = 1), "%"),
                                style = x ~ style(
                                  color = "Green",
                                  background = ifelse(x > 0.10, "rgba(255, 0, 0, 0.2)", "transparent")
                                ))
))
Fecha PromedioIndicadorMora PromedioIndicadorRiesgo
2023-08-31 9.1% 15.2%
2024-08-31 12.2% 17.3%

4. Acciones Importantes en el Dataset

4.1 Nueva Variable: Cumplimiento Indicador Mora

Se valida la variable “Indicadormora”, dando una categoría de acuerdo a su valor.

library(dplyr)
library(tidyr)
library(formattable)

CarteraDatos <- CarteraDatos %>%
  mutate(CategoriaIndicadorMora = cut(Indicadormora,
                                      breaks = c(0, 0.1, 0.2, 0.3, 0.4, Inf),
                                      labels = c("Bajo", "Moderado", "Alto", "Grave", "Crítico"),
                                      right = FALSE,
                                      include.lowest = TRUE)) %>%
  mutate(CategoriaIndicadorMora = ifelse(is.na(CategoriaIndicadorMora), "Sin Mora", as.character(CategoriaIndicadorMora)))


ConteoCategorias <- CarteraDatos %>%
  group_by(Fecha, CategoriaIndicadorMora) %>%
  summarise(Conteo = n()) %>%
  pivot_wider(names_from = Fecha, values_from = Conteo, values_fill = list(Conteo = 0)) 

# Aplicar formattable con color_bar a las columnas de conteo
formattable(ConteoCategorias, list(
  # Aplica barras de datos a todas las columnas excepto la primera
  area(col = 2:ncol(ConteoCategorias)) ~ color_bar("lightblue", fun = "proportion")
))
CategoriaIndicadorMora 2023-08-31 2024-08-31
Alto 7 2
Bajo 95 93
Crítico 4 7
Grave 2 3
Moderado 17 21
Sin Mora 15 14

4.2 Nueva Variable: Cumplimiento Indicador Riesgo

Se valida la variable “Indicadormora”, dando una categoría de acuerdo a su valor.

library(dplyr)

CarteraDatos <- CarteraDatos %>%
  mutate(CategoriaIndicadorRiesgo = cut(Indicadorriesgo,
                                      breaks = c(0, 0.05, 0.1, 0.2, 0.3, Inf),
                                      labels = c("Bajo", "Moderado", "Alto", "Grave", "Crítico"),
                                      right = FALSE,
                                      include.lowest = TRUE)) %>%
  mutate(CategoriaIndicadorRiesgo = ifelse(is.na(CategoriaIndicadorRiesgo), "Sin Riesgo", as.character(CategoriaIndicadorRiesgo)))


ConteoCategoriasRiesgo <- CarteraDatos %>%
  group_by(Fecha, CategoriaIndicadorRiesgo) %>%
  summarise(Conteo = n()) %>%
  pivot_wider(names_from = Fecha, values_from = Conteo, values_fill = list(Conteo = 0)) 

formattable(ConteoCategoriasRiesgo, list(
  area(col = 2:ncol(ConteoCategoriasRiesgo)) ~ color_bar("pink", fun = "proportion")
))
CategoriaIndicadorRiesgo 2023-08-31 2024-08-31
Alto 46 50
Bajo 22 17
Crítico 10 12
Grave 6 7
Moderado 43 43
Sin Riesgo 13 11

4.3 Valores Missing: Indicador Mora

Se identifican los valores nulos.

nulos_Indicadormora <- sum(is.na(CarteraDatos$Indicadormora))

print(paste("Número de valores nulos en Indicadormora:", nulos_Indicadormora))
## [1] "Número de valores nulos en Indicadormora: 29"

Reemplazamos por el percintil 75, de acuerdo a cada fecha de corte.

library(dplyr)

CarteraDatos <- CarteraDatos %>%
  group_by(Fecha) %>%
  mutate(
    percentil_75 = quantile(Indicadormora, 0.75, na.rm = TRUE),
    Indicadormora = ifelse(is.na(Indicadormora), percentil_75, Indicadormora)
  ) %>%
  select(-percentil_75) %>%
  ungroup()

Verificamos nuevamente presencia de nulos.

nulos_Indicadormora <- sum(is.na(CarteraDatos$Indicadormora))

print(paste("Número de valores nulos en Indicadormora:", nulos_Indicadormora))
## [1] "Número de valores nulos en Indicadormora: 0"

4.4 Box Plot: Indicador de Mora

library(ggplot2)
library(dplyr)
library(patchwork)

# Calcular el IQR para identificar y eliminar outliers en Indicadormora
Q1 <- quantile(CarteraDatos$Indicadormora, 0.25, na.rm = TRUE)
Q3 <- quantile(CarteraDatos$Indicadormora, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1

# Filtrar los datos sin outliers
CarteraDatos_no_outliers <- CarteraDatos %>%
  filter(Indicadormora >= (Q1 - 1.5 * IQR) & Indicadormora <= (Q3 + 1.5 * IQR))

# Crear el boxplot con outliers
boxplot_outliers <- ggplot(CarteraDatos, aes(y = Indicadormora)) +
  geom_boxplot(fill = "skyblue", color = "darkblue", outlier.color = "red", outlier.shape = 16) +
  labs(title = "Boxplot con Outliers", y = "Indicador Mora") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, size = 14, face = "bold"))

# Crear el boxplot sin outliers
boxplot_no_outliers <- ggplot(CarteraDatos_no_outliers, aes(y = Indicadormora)) +
  geom_boxplot(fill = "skyblue", color = "darkblue", outlier.shape = NA) +
  labs(title = "Boxplot sin Outliers", y = "Indicador Mora") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, size = 14, face = "bold"))

# Organizar ambos gráficos en una misma fila
boxplot_outliers + boxplot_no_outliers

La presencia de outliers en el primer gráfico indica que existen casos de mora que son significativamente altos en comparación con el resto de la distribución. Al remover los outliers, el segundo gráfico permite observar una distribución más representativa del comportamiento típico de Indicador Mora, donde la mayoría de los datos se concentran en niveles bajos de mora. Al eliminar los outliers, el rango de la caja se extiende, permitiendo ver mejor cómo se distribuyen los datos sin la influencia de valores extremos. La distribución general parece estar en el rango de 0 a 0.15, y el rango intercuartílico (IQR) es más fácil de visualizar.

4.5 Tabla de Contingencia: Modalidad vs Categoría Indicador Riesgo Corte 2023

library(dplyr)

CarteraDatos <- CarteraDatos %>%
  mutate(Fecha = as.character(Fecha))

CarteraDatos_filtrada <- CarteraDatos %>%
  filter(Fecha == "2023-08-31")

tabla_contingencia <- table(CarteraDatos_filtrada$Modalidad, CarteraDatos_filtrada$CategoriaIndicadorRiesgo)



tabla_contingencia
##               
##                Alto Bajo Crítico Grave Moderado Sin Riesgo
##   Comercial      11    5       4     4       15          5
##   Consumo        22    5       2     0       14          0
##   Microcrédito   13    0       3     2        3          3
##   Vivienda        0   12       1     0       11          5

La modalidad de Consumo muestra una tendencia elevada hacia el riesgo, con un alto número de registros en la categoría Alto y una ausencia de créditos en la categoría Sin Riesgo. Esto sugiere que los créditos de consumo son más vulnerables a problemas de mora.

El Microcrédito también muestra una distribución preocupante, con un número considerable en los niveles de Alto y algunos en Crítico y Grave, indicando que los microcréditos están más expuestos a riesgos elevados. Los créditos de vivienda muestran un perfil de riesgo bajo, con la mayoría de los créditos clasificados en Bajo o Moderado, y una pequeña proporción sin riesgo. Esto indica que la modalidad de vivienda es la menos riesgosa en comparación con las otras.

4.6 Prueba de Hipotesis Diferencia de Medias: Indicador Riesgo por Modalidad Corte 2023

Se toma la modalidad de crédito de Comercial y Vivienda para todas las entidades Financieras presentes y se evaluara cual es mayor que la otra.

Planteamiento de la Hipótesis:

Queremos evaluar si el promedio del IndicadorRiesgo en la modalidad de Vivienda es mayor que en la modalidad de Comercial. Para ello, formulamos las siguientes hipótesis:

  • Hipótesis Nula (\(H_0\)): El promedio de IndicadorRiesgo en la modalidad de Vivienda es menor o igual que en la modalidad de Comercial.

    \[ H_0: \mu_{\text{Vivienda}} \leq \mu_{\text{Comercial}} \]

  • Hipótesis Alternativa (\(H_1\)): El promedio de IndicadorRiesgo en la modalidad de Vivienda es mayor que en la modalidad de Comercial.

    \[ H_1: \mu_{\text{Vivienda}} > \mu_{\text{Comercial}} \]

Decisión de la Prueba:

Para validar esta hipótesis, se utilizará una prueba t de dos muestras independientes (con varianzas iguales) y una cola. La hipótesis nula se rechazará si el valor p (\(p\)-value) es menor que el nivel de significancia \(\alpha = 0.05\).

library(dplyr)

CarteraDatos_filtrada <- CarteraDatos %>%
  filter(Fecha == "2023-08-31" & (Modalidad == "Vivienda" | Modalidad == "Comercial"))

# Separar los datos en dos muestras
riesgo_vivienda <- CarteraDatos_filtrada %>% filter(Modalidad == "Vivienda") %>% pull(Indicadorriesgo)
riesgo_comercial <- CarteraDatos_filtrada %>% filter(Modalidad == "Comercial") %>% pull(Indicadorriesgo)

# Realizar la prueba t (una cola, asumiendo varianzas iguales)
t_test <- t.test(riesgo_vivienda, riesgo_comercial, alternative = "greater", var.equal = TRUE)


t_test
## 
##  Two Sample t-test
## 
## data:  riesgo_vivienda and riesgo_comercial
## t = -1.3848, df = 61, p-value = 0.9144
## alternative hypothesis: true difference in means is greater than 0
## 95 percent confidence interval:
##  -0.142813       Inf
## sample estimates:
## mean of x mean of y 
##  0.086825  0.151559

El valor p obtenido es 0.9144, lo cual es mucho mayor que el nivel de significancia común de 0.05. Dado que el valor p es tan alto, no rechazamos la hipótesis nula (H0). Esto significa que no tenemos suficiente evidencia para afirmar que el promedio de IndicadorRiesgo es mayor en Vivienda que en Comercial.

5 Análisis Estadístico

El análisis se centrará sobre el indicador de mora para ambos cortes.

5.1 Indicador de Mora

library(dplyr)
CarteraDatos_23 <- CarteraDatos %>%
  filter(Fecha == "2023-08-31")
CarteraDatos_24 <- CarteraDatos %>%
  filter(Fecha == "2024-08-31")

calcular_metricas <- function(data, variable) {
  resumen <- data %>%
    summarise(
      Minimo = min(!!sym(variable), na.rm = TRUE),
      Maximo = max(!!sym(variable), na.rm = TRUE),
      Rango_Intercuartilico = IQR(!!sym(variable), na.rm = TRUE),
      Media = mean(!!sym(variable), na.rm = TRUE),
      Mediana = median(!!sym(variable), na.rm = TRUE),
      Desviacion = sd(!!sym(variable), na.rm = TRUE),
      Coeficiente_de_Variacion = sd(!!sym(variable), na.rm = TRUE) / mean(!!sym(variable), na.rm = TRUE)
    )
  return(resumen)
}

# Calcular métricas para 2023
metricas_2023 <- calcular_metricas(CarteraDatos_23, "Indicadormora")

# Calcular métricas para 2024
metricas_2024 <- calcular_metricas(CarteraDatos_24, "Indicadormora")


tabla_comparativa <- bind_rows(
  metricas_2023 %>% mutate(Ano = 2023),
  metricas_2024 %>% mutate(Ano = 2024)
) %>%
  pivot_longer(-Ano, names_to = "Metrica", values_to = "Valor") %>%
  pivot_wider(names_from = Ano, values_from = Valor)



formattable(
  tabla_comparativa,
  list(
    `2023` = formatter("span", style = x ~ style(
      display = "block",
      `background-color` = csscolor(
        gradient((x - min(tabla_comparativa$`2023`, tabla_comparativa$`2024`, na.rm = TRUE)) /
                   (max(tabla_comparativa$`2023`, tabla_comparativa$`2024`, na.rm = TRUE) - 
                      min(tabla_comparativa$`2023`, tabla_comparativa$`2024`, na.rm = TRUE)), 
                 "pink", "lightblue")
      )
    )),
    `2024` = formatter("span", style = x ~ style(
      display = "block",
      `background-color` = csscolor(
        gradient((x - min(tabla_comparativa$`2023`, tabla_comparativa$`2024`, na.rm = TRUE)) /
                   (max(tabla_comparativa$`2023`, tabla_comparativa$`2024`, na.rm = TRUE) - 
                      min(tabla_comparativa$`2023`, tabla_comparativa$`2024`, na.rm = TRUE)), 
                 "lightblue", "pink")
      )
    ))
  )
)
Metrica 2023 2024
Minimo 0.0005000 0.0048000
Maximo 1.0000000 1.0000000
Rango_Intercuartilico 0.0582500 0.0593750
Media 0.1014779 0.1177893
Mediana 0.0631500 0.0716500
Desviacion 0.1630520 0.1867808
Coeficiente_de_Variacion 1.6067745 1.5857198

En términos del valor mínimo, se observa que en 2023 el valor más bajo registrado fue de 0.0005, mientras que en 2024 fue de 0.0048. Esto indica que, en 2024, incluso las entidades con mejor desempeño tuvieron un nivel de mora superior al del año anterior. El valor máximo, sin embargo, se mantuvo constante en 1.0 en ambos años, lo que significa que las situaciones más críticas de mora no empeoraron entre los períodos.

La media y la mediana del indicador de mora también reflejan un aumento en 2024. La media pasó de 0.1015 en 2023 a 0.1178 en 2024, mientras que la mediana aumentó de 0.0632 a 0.0717. Esto sugiere que no solo el promedio general de mora aumentó, sino que la mitad de las entidades ahora tienen un nivel de mora superior al de 2023. Este incremento en la media y la mediana indica un deterioro generalizado en la calidad de la cartera.

En cuanto a la variabilidad, la desviación estándar pasó de 0.1635 en 2023 a 0.1868 en 2024, lo que muestra una mayor dispersión de los valores en el año más reciente. Además, el rango intercuartílico, que mide la dispersión entre el primer y el tercer cuartil, también se incrementó ligeramente, lo que indica que la variabilidad en los valores intermedios de mora fue mayor en 2024.

Finalmente, el coeficiente de variación, que relaciona la desviación estándar con la media, muestra una leve disminución de 1.61 en 2023 a 1.59 en 2024. Esto implica que, aunque la variabilidad absoluta aumentó, la dispersión relativa respecto al promedio se redujo ligeramente.

library(ggplot2)
library(gridExtra)
# Histogramas para 2023 y 2024
hist_2023 <- ggplot(CarteraDatos_23, aes(x = Indicadormora)) +
  geom_histogram(binwidth = 0.02, fill = "pink", color = "black", alpha = 0.7) +
  theme_minimal() +
  ggtitle("Histograma Indicador Mora - 2023") +
  xlab("Indicador de Mora") +
  ylab("Frecuencia") +
  theme(plot.title = element_text(hjust = 0.5))

hist_2024 <- ggplot(CarteraDatos_24, aes(x = Indicadormora)) +
  geom_histogram(binwidth = 0.02, fill = "lightblue", color = "black", alpha = 0.7) +
  theme_minimal() +
  ggtitle("Histograma Indicador Mora - 2024") +
  xlab("Indicador de Mora") +
  ylab("Frecuencia") +
  theme(plot.title = element_text(hjust = 0.5))

# Boxplots para 2023 y 2024
boxplot_2023 <- ggplot(CarteraDatos_23, aes(y = Indicadormora)) +
  geom_boxplot(fill = "pink", color = "black") +
  theme_minimal() +
  ggtitle("Boxplot Indicador Mora - 2023") +
  ylab("Indicador de Mora") +
  theme(plot.title = element_text(hjust = 0.5))

boxplot_2024 <- ggplot(CarteraDatos_24, aes(y = Indicadormora)) +
  geom_boxplot(fill = "lightblue", color = "black") +
  theme_minimal() +
  ggtitle("Boxplot Indicador Mora - 2024") +
  ylab("Indicador de Mora") +
  theme(plot.title = element_text(hjust = 0.5))

# Organizar gráficos lado a lado
grid.arrange(hist_2023, hist_2024, ncol = 2)

grid.arrange(boxplot_2023, boxplot_2024, ncol = 2)

En 2023, la mayoría de los valores del indicador de mora se concentran cerca del 0, lo que indica que un gran número de entidades tienen niveles bajos de mora. La distribución muestra un sesgo hacia la derecha, con pocos valores que superan 0.25. Existen algunos valores aislados cercanos a 1, pero son excepcionales, lo que sugiere que solo unas pocas entidades enfrentan niveles críticos de mora.

En 2024, la distribución sigue una tendencia similar, con la mayoría de los valores aún concentrados cerca de 0. Sin embargo, se nota un desplazamiento hacia valores más altos, lo que indica un ligero aumento generalizado en la mora. En este año, hay una mayor dispersión de los datos, con más entidades alcanzando niveles de mora entre 0.25 y 0.75. Además, los valores cercanos a 1 son más frecuentes que en 2023, evidenciando un crecimiento en el número de entidades con mora crítica.

Los datos reflejan un deterioro en el comportamiento del indicador de mora en 2024 en comparación con 2023. Este cambio sugiere que, aunque la mayoría de las entidades siguen teniendo niveles bajos de mora, hay un incremento significativo en la cantidad de entidades con niveles más altos.

# Densidad Comparativa para 2023 y 2024
densidad_comparativa <- ggplot() +
  geom_density(data = CarteraDatos_23, aes(x = Indicadormora, fill = "2023"), alpha = 0.5) +
  geom_density(data = CarteraDatos_24, aes(x = Indicadormora, fill = "2024"), alpha = 0.5) +
  theme_minimal() +
  ggtitle("Comparación de Densidad - Indicador Mora 2023 vs 2024") +
  xlab("Indicador de Mora") +
  ylab("Densidad") +
  theme(plot.title = element_text(hjust = 0.5)) +
  scale_fill_manual(values = c("2023" = "pink", "2024" = "lightblue"), name = "Año")

# Mostrar gráfico
print(densidad_comparativa)

library(dplyr)

CarteraDatos_23 <- CarteraDatos %>%
  filter(Fecha == "2023-08-31")

CarteraDatos_24 <- CarteraDatos %>%
  filter(Fecha == "2024-08-31")

n_2023 <- nrow(CarteraDatos_23)
k_2023 <- round(1 + 3.322 * log10(n_2023))  # Número de intervalos usando la regla de Sturges

# Crear intervalos usando cut
intervalos_2023 <- cut(CarteraDatos_23$Indicadormora, breaks = k_2023, right = TRUE)

# Generar la tabla de frecuencias
tab_2023 <- as.data.frame(table(intervalos_2023))

# Calcular frecuencia acumulada, relativa y relativa acumulada
tab_2023 <- transform(tab_2023, 
                      FreqAc = cumsum(Freq), 
                      Rel = round(Freq / sum(Freq), 4),  # Frecuencia relativa
                      RelAc = round(cumsum(Freq / sum(Freq)), 4))  # Frecuencia relativa acumulada

print(tab_2023)
##     intervalos_2023 Freq FreqAc    Rel  RelAc
## 1 (-0.000499,0.125]  120    120 0.8571 0.8571
## 2      (0.125,0.25]   12    132 0.0857 0.9429
## 3      (0.25,0.375]    3    135 0.0214 0.9643
## 4       (0.375,0.5]    1    136 0.0071 0.9714
## 5       (0.5,0.625]    0    136 0.0000 0.9714
## 6      (0.625,0.75]    0    136 0.0000 0.9714
## 7      (0.75,0.875]    0    136 0.0000 0.9714
## 8         (0.875,1]    4    140 0.0286 1.0000
# Calcular tabla de distribución de frecuencias para 2024
n_2024 <- nrow(CarteraDatos_24)
k_2024 <- round(1 + 3.322 * log10(n_2024))  # Número de intervalos usando la regla de Sturges

# Crear intervalos usando cut
intervalos_2024 <- cut(CarteraDatos_24$Indicadormora, breaks = k_2024, right = TRUE)

# Generar la tabla de frecuencias
tab_2024 <- as.data.frame(table(intervalos_2024))

# Calcular frecuencia acumulada, relativa y relativa acumulada
tab_2024 <- transform(tab_2024, 
                      FreqAc = cumsum(Freq), 
                      Rel = round(Freq / sum(Freq), 4),  # Frecuencia relativa
                      RelAc = round(cumsum(Freq / sum(Freq)), 4))  # Frecuencia relativa acumulada
formattable(tab_2023)
intervalos_2023 Freq FreqAc Rel RelAc
(-0.000499,0.125] 120 120 0.8571 0.8571
(0.125,0.25] 12 132 0.0857 0.9429
(0.25,0.375] 3 135 0.0214 0.9643
(0.375,0.5] 1 136 0.0071 0.9714
(0.5,0.625] 0 136 0.0000 0.9714
(0.625,0.75] 0 136 0.0000 0.9714
(0.75,0.875] 0 136 0.0000 0.9714
(0.875,1] 4 140 0.0286 1.0000
formattable(tab_2024)
intervalos_2024 Freq FreqAc Rel RelAc
(0.0038,0.129] 117 117 0.8357 0.8357
(0.129,0.254] 12 129 0.0857 0.9214
(0.254,0.378] 4 133 0.0286 0.9500
(0.378,0.502] 1 134 0.0071 0.9571
(0.502,0.627] 1 135 0.0071 0.9643
(0.627,0.751] 0 135 0.0000 0.9643
(0.751,0.876] 0 135 0.0000 0.9643
(0.876,1] 5 140 0.0357 1.0000

En el corte de 2023, la mayor concentración de entidades se encuentra en el intervalo más bajo del indicador de mora, (0.000, 0.125], que representa el 85.7% del total de observaciones. A medida que se avanza hacia intervalos superiores, la frecuencia disminuye drásticamente, con los intervalos más altos, como (0.875, 1], representando solo un 2.86% de las entidades. Esto sugiere que la mayoría de las entidades tienen niveles bajos de mora, con pocos casos extremos. La frecuencia acumulada muestra que el 97.1% de las observaciones está concentrado en los primeros cuatro intervalos, lo que refuerza la idea de una cartera predominantemente saludable en términos de mora. La frecuencia relativa acumulada alcanza el 100% en el último intervalo, reflejando que los valores altos de mora son poco comunes.

En el corte de 2024, se mantiene una concentración importante en el intervalo más bajo, (0.0038, 0.129], que abarca el 83.6% de las entidades. Sin embargo, se observa un ligero incremento en la dispersión hacia intervalos superiores en comparación con 2023. El intervalo más alto (0.876, 1] presenta un 3.57% de las observaciones, un aumento respecto al año anterior, lo que indica que más entidades alcanzaron niveles críticos de mora. La frecuencia acumulada muestra que más del 95% de las observaciones se encuentran en los primeros cinco intervalos, pero con una mayor presencia de casos en intervalos intermedios y altos. La frecuencia relativa acumulada también alcanza el 100% en el último intervalo, reflejando una mayor proporción de entidades con niveles elevados de mora en comparación con 2023.

library(dplyr)

CarteraDatos_24 <- CarteraDatos %>%
  filter(Fecha == "2024-08-31")

CarteraDatos_24 <- CarteraDatos_24 %>%
  mutate(
    Fecha = as.Date(Fecha),  # Asegurarse de que Fecha sea tipo Date
    Tipoentidad = as.factor(Tipoentidad),
    Modalidad = as.factor(Modalidad)
  )

# Ajustar el modelo de regresión lineal
modelo <- lm(Saldomora ~ Fecha + Tipoentidad + Modalidad + Saldobruto, data = CarteraDatos)

# Resumen del modelo
summary(modelo)
## 
## Call:
## lm(formula = Saldomora ~ Fecha + Tipoentidad + Modalidad + Saldobruto, 
##     data = CarteraDatos)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1104271  -121602   -10236    55080  2355741 
## 
## Coefficients:
##                            Estimate    Std. Error t value             Pr(>|t|)
## (Intercept)           -54074.100984  44151.346478  -1.225                0.222
## Fecha2024-08-31        13651.471538  38155.562933   0.358                0.721
## Tipoentidad             -936.614188   1781.873494  -0.526                0.600
## ModalidadConsumo      212865.820463  48413.189843   4.397            0.0000164
## ModalidadMicrocrédito  92134.103487  59112.207009   1.559                0.120
## ModalidadVivienda       2720.095047  56009.542455   0.049                0.961
## Saldobruto                 0.043773      0.001438  30.443 < 0.0000000000000002
##                          
## (Intercept)              
## Fecha2024-08-31          
## Tipoentidad              
## ModalidadConsumo      ***
## ModalidadMicrocrédito    
## ModalidadVivienda        
## Saldobruto            ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 301900 on 244 degrees of freedom
##   (29 observations deleted due to missingness)
## Multiple R-squared:  0.8041, Adjusted R-squared:  0.7993 
## F-statistic: 166.9 on 6 and 244 DF,  p-value: < 0.00000000000000022

El modelo de regresión lineal tiene como objetivo explicar la variabilidad en el Saldomora a partir de las variables Fecha, Tipoentidad, Modalidad, y Saldobruto. El modelo presenta un buen ajuste, con un R-cuadrado ajustado de 0.7979, lo que indica que aproximadamente el 79.79% de la variabilidad en Saldomora es explicada por las variables independientes incluidas en el modelo. Además, el modelo es estadísticamente significativo en su conjunto, ya que la prueba F muestra un p-valor extremadamente bajo (p < 0.0001), lo que indica que las variables independientes, como un grupo, tienen un efecto significativo en la variable dependiente.

En cuanto a los coeficientes, Saldobruto es la variable más importante, con un coeficiente estimado de 0.0436. Esto implica que, por cada unidad adicional en Saldobruto, el Saldomora aumenta en promedio 0.0436 unidades, manteniendo constantes las demás variables. Este coeficiente es altamente significativo, con un p-valor menor a 0.0001, lo que refuerza su relevancia en la explicación del saldo de mora.

La variable Modalidad también muestra un impacto relevante. Específicamente, la modalidad Consumo tiene un coeficiente estimado de 214,435, lo que sugiere que las entidades con esta modalidad tienden a tener un Saldomora significativamente mayor en comparación con la categoría de referencia. Este efecto es altamente significativo con un p-valor de 0.0000158. Por otro lado, las modalidades Microcrédito y Vivienda no muestran efectos estadísticamente significativos, con p-valores de 0.146 y 0.981, respectivamente.

Las variables Fecha y Tipoentidad no presentan un efecto significativo sobre Saldomora. Los coeficientes para estas variables son relativamente pequeños y sus p-valores son mayores a 0.05, lo que indica que no contribuyen de manera sustancial a la explicación de la variabilidad en el saldo de mora.

library(MASS)
CarteraDatos <- CarteraDatos %>%
  mutate(CategoriaIndicadorMora_ = cut(Indicadormora,
                                      breaks = c(0, 0.5, Inf),
                                      labels = c("No Default", "Default"),
                                      right = FALSE,
                                      include.lowest = TRUE)) %>%
  mutate(CategoriaIndicadorMora_ = ifelse(is.na(CategoriaIndicadorMora), "No Default", as.character(CategoriaIndicadorMora)))

CarteraDatos$CategoriaIndicadorMora_ <- as.factor(CarteraDatos$CategoriaIndicadorMora)
modelo_logit <- glm(CategoriaIndicadorMora_ ~ Tipoentidad + Modalidad + Saldobruto + Fecha, 
                    data = CarteraDatos, 
                    family = binomial(link = "logit"))
summary(modelo_logit)
## 
## Call:
## glm(formula = CategoriaIndicadorMora_ ~ Tipoentidad + Modalidad + 
##     Saldobruto + Fecha, family = binomial(link = "logit"), data = CarteraDatos)
## 
## Coefficients:
##                             Estimate     Std. Error z value Pr(>|z|)  
## (Intercept)              0.549205584    0.727045021   0.755   0.4500  
## Tipoentidad              0.015584078    0.031322960   0.498   0.6188  
## ModalidadConsumo        18.048143523 2274.221640269   0.008   0.9937  
## ModalidadMicrocrédito   -0.472860179    0.790579215  -0.598   0.5498  
## ModalidadVivienda       18.682961739 3032.231327684   0.006   0.9951  
## Saldobruto               0.000011633    0.000006444   1.805   0.0710 .
## Fecha2024-08-31          1.690932894    0.895182923   1.889   0.0589 .
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 79.053  on 271  degrees of freedom
## Residual deviance: 42.841  on 265  degrees of freedom
##   (8 observations deleted due to missingness)
## AIC: 56.841
## 
## Number of Fisher Scoring iterations: 20
exp(coef(modelo_logit))
##           (Intercept)           Tipoentidad      ModalidadConsumo 
##             1.7318766             1.0157061      68898400.6309964 
## ModalidadMicrocrédito     ModalidadVivienda            Saldobruto 
##             0.6232172     129989175.4516116             1.0000116 
##       Fecha2024-08-31 
##             5.4245389

El modelo de regresión logística binaria se utiliza para predecir la probabilidad de que una observación pertenezca a la categoría “Default” de la variable dependiente CategoriaIndicadorMora, basándose en las variables independientes Tipoentidad, Modalidad, Saldobruto, y Fecha. Sin embargo, los resultados indican que ninguno de los predictores tiene un efecto estadísticamente significativo sobre la probabilidad de Default, ya que todos los p-valores son superiores a 0.05.

El intercepto tiene un valor estimado de 52.85, pero con un p-valor de 0.496, lo que indica que no es estadísticamente significativo. Esto sugiere que, cuando todas las variables independientes son cero, no se puede establecer con confianza una probabilidad base de Default.

En conclusión, aunque el modelo ajusta los datos hasta cierto punto, no encuentra evidencia estadísticamente significativa de que las variables independientes utilizadas sean buenos predictores de la probabilidad de Default. Esto resalta la necesidad de explorar otras variables explicativas o mejorar la calidad de los datos disponibles.