A continuacion presentamos el codigo para la construcción de un modelo de regresión logística binaria, arbol de decisiones y XGboost con y sin ponderación por clase, para predecir el riesgo de incumplimiento crediticio. Este análisis se basa en una base de datos previamente depurada y preparada, con un enfoque en la evaluación comparativa de ambos enfoques.
Se cargan las librerías necesarias para la manipulación de datos, modelado y evaluación de modelos. Se establece una semilla para garantizar la reproducibilidad de los resultados.
library(tidyverse) # Manipulación y visualización de datos
library(caret) # Partición, preprocesamiento y métricas
library(readxl) # Lectura de archivos Excel
library(pROC) # Curvas ROC y AUC
library(rpart) # Árbol de decisión
library(rpart.plot) # Visualización del árbol
library(xgboost) # Gradient Boosting
set.seed(2930) # Semilla para reproducibilidadEn esta etapa se realizó el carge de la base de datos desde un archivo en formato Excel. Posteriormente, se llevó a cabo un proceso de depuración orientado a eliminar variables de carácter administrativo o de identificacion, las cuales no aportan valor explicativo al modelo y podrían introducir ruido en la estimación.
Adicionalmente, todas las variables de tipo carácter fueron transformadas a formato categórico (factor), con el fin de ser correctamente interpretadas dentro de los modelos.
df <- read_excel("C:/JOHAN SEBASTIAN/MAESTRIA - CIENCIA DE DATOS/TERCER SEMESTRE/PROYECTO APLICADO III/df_limpio.xlsx") # Carga base de datos desde Excel
df <- df %>%
dplyr::select(
-numero_banco, -fecha_prox_ven, -tipo_cartera,
-fecha_inicio_op, -fecha_ven_op, -tipo_identificacion,
-mo_nombre_cliente, -id
) %>% # Elimina variables irrelevantes o identificadores
mutate(across(where(is.character), as.factor)) # Convierte texto a factores
print(df)## # A tibble: 55,454 × 34
## zonal nombre_oficina Longitud Latitud dias_vencido rango saldo
## <fct> <fct> <dbl> <dbl> <dbl> <fct> <dbl>
## 1 Nariño CHACHAGUI -77.3 1.36 0 0 días 1.24 e7
## 2 Cauca POPAYAN SUCURSAL -76.6 2.46 107 Mayor a 90 días 1.18 e7
## 3 Cauca PURACE -76.5 2.34 0 0 días 2.40 e6
## 4 Nariño RICAURTE -78.0 1.21 0 0 días 1.000e6
## 5 Nariño PASTO SUCURSAL -77.3 1.21 0 0 días 1.07 e6
## 6 Cauca BALBOA (CAUCA) -77.2 2.04 0 0 días 5.09 e6
## 7 Cauca SUAREZ (CAUCA) -76.7 2.96 0 0 días 2.17 e6
## 8 Cauca POPAYAN SUCURSAL -76.6 2.46 0 0 días 6 e6
## 9 Cauca POPAYAN SUCURSAL -76.6 2.46 0 0 días 1.84 e7
## 10 Cauca CAJIBIO -76.6 2.62 0 0 días 3.57 e5
## # ℹ 55,444 more rows
## # ℹ 27 more variables: Banca_cliente <fct>, genero <fct>,
## # ciudad_inversion <fct>, Departamento_Inversion <fct>, longitud_inver <fct>,
## # latitud_inver <dbl>, monto_desembolso <dbl>, calificacion_obligacion <fct>,
## # mo_modalidad <fct>, valor_vencido <dbl>, saldo_cuota_prox_venc <dbl>,
## # etapa <fct>, estado_obligacion <fct>, cuotas_pagadas <dbl>,
## # cuotas_pactadas <dbl>, cero_cuotas_pagadas <fct>, reestructurada <fct>, …
Dado el alto número de categorías en algunas variables, se implementaron técnicas de recodificación para reducir la dimensionalidad y evitar problemas de sobreajuste.
# Reducimos cardinalidad de variables con muchos niveles, agrupando los menos frecuentes en "Otros"
df$`Tipo Factor Externo` <- fct_collapse(
df$`Tipo Factor Externo`,
Económico = c("Económico", "Orden Público"),
Sequía = c("Sequía", "Sequía y Heladas")
)
table(df$`Tipo Factor Externo`)##
## Económico Factores Naturales - Volcán
## 15088 195
## Ola Invernal Sequía
## 39729 442
# Reducimos cardinalidad de variables con muchos niveles, agrupando los menos frecuentes en "Otros"
df$hecho_victimizante <- fct_lump_min(df$hecho_victimizante, min = 30)
table(df$`Tipo Factor Externo`)##
## Económico Factores Naturales - Volcán
## 15088 195
## Ola Invernal Sequía
## 39729 442
# Reducimos cardinalidad de variables con muchos niveles, agrupando los menos frecuentes en "Otros"
df$tipo_de_producto <- fct_lump_min(df$tipo_de_producto, 50)
table(df$tipo_de_producto)##
## CAP TRABAJO MICROCREDITO MULTIDESTINO CAP TRABAJO MUJER MICROEMPRESARIA
## 81 364
## CAP. TRABAJO PROYECTO MICROCREDITO CAPITAL DE TRABAJO ORDINARIA FINAGRO
## 65 2626
## INV. VICTIMA CONFLICTO ARMADO INTERNO INVERSION - COMP. ANIM.Y RETEN.VIENTRES
## 1702 90
## INVERSION - PLANTACION Y MANTENIMIENTO INVERSION MUJER MICROEMPRESARIA
## 2682 327
## INVERSIÓN MULTIDESTINO IBR INVERSION MULTIDESTINO MICRO
## 105 109
## INVERSION ORDINARIA FINAGRO INVERSIÓN PROYECTO MICROCREDITO
## 46859 77
## MICROCREDITO ECONOMIA POPULAR RP NORMALIZACION DE RECURSOS FINAGRO IBR
## 125 65
## Other
## 177
# Reducimos cardinalidad de variables con muchos niveles, agrupando los menos frecuentes en "Otros"
df$Departamento_Inversion <- fct_lump_min(df$Departamento_Inversion, 30)
table(df$Departamento_Inversion)##
## Cauca Nariño Valle del cauca Valle del Cauca Other
## 25524 27662 2172 35 61
# Reducimos cardinalidad de variables con muchos niveles, agrupando los menos frecuentes en "Otros"
df$tasa_referencial <- fct_lump_min(df$tasa_referencial, 30)
table(df$tasa_referencial)##
## INDICADOR BANCARIO DE REFERENCIA MENSUAL
## 251
## INDICADOR BANCARIO DE REFERENCIA SEMESTRAL
## 44703
## INDICADOR BANCARIO DE REFERENCIA TRIMESTRAL
## 1722
## TASA Cero
## 1151
## Tasa DTF Efectivo Anual
## 7612
## Other
## 15
Se definió un conjunto de variables explicativas basado en criterios teóricos como PCA, MCA y Factor Analysis of Mixed Data (FAMD), y empíricos relevantes para el análisis del riesgo crediticio
var_sele <- c(
"tipo_de_producto", "tasa_referencial", "tipo_productor_pmg",
"destino_agrupado", "Banca_cliente", "mo_modalidad",
"Departamento_Inversion",
"cuotas_pactadas", "Tipo Factor Externo",
"monto_desembolso", "saldo",
"COMPARATIVO_OCURRENCIA_HECHO",
"genero", "hecho_victimizante",
"rango", "dias_vencido"
)
df_modelo <- df[, var_sele]Se construyó una variable dependiente binaria denominada target_binario, donde:
“Al Día”: créditos sin mora (0 días) “En Mora”: créditos con algún nivel de incumplimiento
Esta transformación permite modelar el problema como una clasificación binaria, donde el interés principal es identificar el riesgo de incumplimiento.
## Distribución target_binario:
##
## Al Día En Mora
## 48263 7191
## Proporción:
##
## Al Día En Mora
## 0.870325 0.129675
Se dividió la base de datos en:
# createDataPartition garantiza proporciones similares en train y test
train_idx <- createDataPartition(df_modelo$target_binario, p = 0.7, list = FALSE)
train_bin <- df_modelo[train_idx, ] # Datos de entrenamiento (70%)
test_bin <- df_modelo[-train_idx, ] # Datos de validación (30%)
cat("\nTamaño train:", nrow(train_bin), "| test:", nrow(test_bin), "\n")##
## Tamaño train: 38819 | test: 16635
Las variables numéricas relevantes fueron estandarizadas (media cero y varianza uno) utilizando únicamente los datos de entrenamiento, evitando así problemas de data leakage.
# Seleccionamos las variables numericas para escalado
vars_num <- c("cuotas_pactadas", "monto_desembolso", "saldo")
# Creamos objeto preProcess con parámetros de escalado basados solo en train
preproc_bin <- preProcess(train_bin[, vars_num], method = c("center", "scale"))
# Aplicamos la transformación a train y test usando el mismo preproc
train_bin[, vars_num] <- predict(preproc_bin, train_bin[, vars_num])
test_bin[, vars_num] <- predict(preproc_bin, test_bin[, vars_num])
# Renombrar variable con espacios
train_bin <- train_bin %>% rename(Tipo_Factor_Externo = `Tipo Factor Externo`)
test_bin <- test_bin %>% rename(Tipo_Factor_Externo = `Tipo Factor Externo`)Este modelo se realiza utilizando todas las variables seleccionadas como predictores, Ademas servirá como referencia para evaluar el impacto de la ponderación en el siguiente paso.
##
## ====== MODELO LOGIT SIN PESOS ======
model_logit <- glm(
target_binario ~ tipo_de_producto + tasa_referencial + tipo_productor_pmg +
destino_agrupado + Banca_cliente + mo_modalidad +
Tipo_Factor_Externo + factor(Departamento_Inversion) + genero +
cuotas_pactadas + monto_desembolso + saldo +
COMPARATIVO_OCURRENCIA_HECHO,
data = train_bin,
family = binomial(link = "logit")
)
print(summary(model_logit))##
## Call:
## glm(formula = target_binario ~ tipo_de_producto + tasa_referencial +
## tipo_productor_pmg + destino_agrupado + Banca_cliente + mo_modalidad +
## Tipo_Factor_Externo + factor(Departamento_Inversion) + genero +
## cuotas_pactadas + monto_desembolso + saldo + COMPARATIVO_OCURRENCIA_HECHO,
## family = binomial(link = "logit"), data = train_bin)
##
## Coefficients:
## Estimate
## (Intercept) -12.47184
## tipo_de_productoCAP TRABAJO MUJER MICROEMPRESARIA -0.77832
## tipo_de_productoCAP. TRABAJO PROYECTO MICROCREDITO 0.29182
## tipo_de_productoCAPITAL DE TRABAJO ORDINARIA FINAGRO 2.64366
## tipo_de_productoINV. VICTIMA CONFLICTO ARMADO INTERNO 3.43007
## tipo_de_productoINVERSION - COMP. ANIM.Y RETEN.VIENTRES 4.73300
## tipo_de_productoINVERSION - PLANTACION Y MANTENIMIENTO 3.90782
## tipo_de_productoINVERSION MUJER MICROEMPRESARIA -0.83688
## tipo_de_productoINVERSIÓN MULTIDESTINO IBR 1.42929
## tipo_de_productoINVERSION MULTIDESTINO MICRO -0.42110
## tipo_de_productoINVERSION ORDINARIA FINAGRO 3.57661
## tipo_de_productoINVERSIÓN PROYECTO MICROCREDITO -0.32129
## tipo_de_productoMICROCREDITO ECONOMIA POPULAR RP -0.98645
## tipo_de_productoNORMALIZACION DE RECURSOS FINAGRO IBR 4.40109
## tipo_de_productoOther 2.53346
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA SEMESTRAL -4.28604
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA TRIMESTRAL -4.38210
## tasa_referencialTASA Cero -0.05297
## tasa_referencialTasa DTF Efectivo Anual -3.73369
## tasa_referencialOther 2.60602
## tipo_productor_pmgGran Productor Finagro 2.00461
## tipo_productor_pmgMediano Productor 11.21681
## tipo_productor_pmgMicrofinanzas 11.97727
## tipo_productor_pmgNo Agropecuario 10.93068
## tipo_productor_pmgPequeño Productor 11.92805
## destino_agrupadoAgricultura - cultivos -1.42156
## destino_agrupadoComercializacion - transformacion agropecuaria -2.12417
## destino_agrupadoFinancieros - capital de trabajo -0.94813
## destino_agrupadoInfraestructura - equipamiento -1.93578
## destino_agrupadoPecuaria - pesca -1.35750
## destino_agrupadoServicio - apoyo agropecuario -1.53022
## Banca_clienteMICROFINANZAS 0.08470
## Banca_clientePERSONAL -0.24445
## mo_modalidadMV 0.84004
## mo_modalidadSV 0.46197
## mo_modalidadTV 1.72290
## Tipo_Factor_ExternoFactores Naturales - Volcán 0.28545
## Tipo_Factor_ExternoOla Invernal 0.54353
## Tipo_Factor_ExternoSequía 0.15357
## factor(Departamento_Inversion)Nariño -0.33957
## factor(Departamento_Inversion)Valle del cauca 0.33930
## factor(Departamento_Inversion)Valle del Cauca -0.39874
## factor(Departamento_Inversion)Other -0.46994
## generoMASCULINO 0.11085
## cuotas_pactadas -0.55295
## monto_desembolso -0.50926
## saldo 0.54665
## COMPARATIVO_OCURRENCIA_HECHONo reporta -0.31539
## COMPARATIVO_OCURRENCIA_HECHOV-D -0.01765
## Std. Error
## (Intercept) 107.68920
## tipo_de_productoCAP TRABAJO MUJER MICROEMPRESARIA 0.46667
## tipo_de_productoCAP. TRABAJO PROYECTO MICROCREDITO 0.56749
## tipo_de_productoCAPITAL DE TRABAJO ORDINARIA FINAGRO 1.35321
## tipo_de_productoINV. VICTIMA CONFLICTO ARMADO INTERNO 1.36858
## tipo_de_productoINVERSION - COMP. ANIM.Y RETEN.VIENTRES 1.40845
## tipo_de_productoINVERSION - PLANTACION Y MANTENIMIENTO 1.36787
## tipo_de_productoINVERSION MUJER MICROEMPRESARIA 0.47953
## tipo_de_productoINVERSIÓN MULTIDESTINO IBR 1.26220
## tipo_de_productoINVERSION MULTIDESTINO MICRO 0.54916
## tipo_de_productoINVERSION ORDINARIA FINAGRO 1.36599
## tipo_de_productoINVERSIÓN PROYECTO MICROCREDITO 0.60528
## tipo_de_productoMICROCREDITO ECONOMIA POPULAR RP 0.55929
## tipo_de_productoNORMALIZACION DE RECURSOS FINAGRO IBR 1.40349
## tipo_de_productoOther 1.32583
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA SEMESTRAL 0.39971
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA TRIMESTRAL 0.89431
## tasa_referencialTASA Cero 1.20222
## tasa_referencialTasa DTF Efectivo Anual 0.41257
## tasa_referencialOther 1.05428
## tipo_productor_pmgGran Productor Finagro 342.13131
## tipo_productor_pmgMediano Productor 107.67884
## tipo_productor_pmgMicrofinanzas 107.67966
## tipo_productor_pmgNo Agropecuario 107.68042
## tipo_productor_pmgPequeño Productor 107.67860
## destino_agrupadoAgricultura - cultivos 0.92497
## destino_agrupadoComercializacion - transformacion agropecuaria 1.01848
## destino_agrupadoFinancieros - capital de trabajo 0.91037
## destino_agrupadoInfraestructura - equipamiento 0.95354
## destino_agrupadoPecuaria - pesca 0.92645
## destino_agrupadoServicio - apoyo agropecuario 0.92871
## Banca_clienteMICROFINANZAS 0.26858
## Banca_clientePERSONAL 0.43573
## mo_modalidadMV 0.26166
## mo_modalidadSV 0.13902
## mo_modalidadTV 0.82170
## Tipo_Factor_ExternoFactores Naturales - Volcán 0.27500
## Tipo_Factor_ExternoOla Invernal 0.07884
## Tipo_Factor_ExternoSequía 0.20750
## factor(Departamento_Inversion)Nariño 0.03747
## factor(Departamento_Inversion)Valle del cauca 0.06837
## factor(Departamento_Inversion)Valle del Cauca 0.61247
## factor(Departamento_Inversion)Other 0.61229
## generoMASCULINO 0.03145
## cuotas_pactadas 0.03085
## monto_desembolso 0.05196
## saldo 0.04158
## COMPARATIVO_OCURRENCIA_HECHONo reporta 0.10746
## COMPARATIVO_OCURRENCIA_HECHOV-D 0.10798
## z value Pr(>|z|)
## (Intercept) -0.116 0.907801
## tipo_de_productoCAP TRABAJO MUJER MICROEMPRESARIA -1.668 0.095354
## tipo_de_productoCAP. TRABAJO PROYECTO MICROCREDITO 0.514 0.607098
## tipo_de_productoCAPITAL DE TRABAJO ORDINARIA FINAGRO 1.954 0.050745
## tipo_de_productoINV. VICTIMA CONFLICTO ARMADO INTERNO 2.506 0.012200
## tipo_de_productoINVERSION - COMP. ANIM.Y RETEN.VIENTRES 3.360 0.000778
## tipo_de_productoINVERSION - PLANTACION Y MANTENIMIENTO 2.857 0.004279
## tipo_de_productoINVERSION MUJER MICROEMPRESARIA -1.745 0.080951
## tipo_de_productoINVERSIÓN MULTIDESTINO IBR 1.132 0.257475
## tipo_de_productoINVERSION MULTIDESTINO MICRO -0.767 0.443195
## tipo_de_productoINVERSION ORDINARIA FINAGRO 2.618 0.008836
## tipo_de_productoINVERSIÓN PROYECTO MICROCREDITO -0.531 0.595546
## tipo_de_productoMICROCREDITO ECONOMIA POPULAR RP -1.764 0.077772
## tipo_de_productoNORMALIZACION DE RECURSOS FINAGRO IBR 3.136 0.001714
## tipo_de_productoOther 1.911 0.056024
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA SEMESTRAL -10.723 < 2e-16
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA TRIMESTRAL -4.900 9.58e-07
## tasa_referencialTASA Cero -0.044 0.964854
## tasa_referencialTasa DTF Efectivo Anual -9.050 < 2e-16
## tasa_referencialOther 2.472 0.013442
## tipo_productor_pmgGran Productor Finagro 0.006 0.995325
## tipo_productor_pmgMediano Productor 0.104 0.917035
## tipo_productor_pmgMicrofinanzas 0.111 0.911434
## tipo_productor_pmgNo Agropecuario 0.102 0.919145
## tipo_productor_pmgPequeño Productor 0.111 0.911795
## destino_agrupadoAgricultura - cultivos -1.537 0.124323
## destino_agrupadoComercializacion - transformacion agropecuaria -2.086 0.037013
## destino_agrupadoFinancieros - capital de trabajo -1.041 0.297655
## destino_agrupadoInfraestructura - equipamiento -2.030 0.042346
## destino_agrupadoPecuaria - pesca -1.465 0.142846
## destino_agrupadoServicio - apoyo agropecuario -1.648 0.099417
## Banca_clienteMICROFINANZAS 0.315 0.752476
## Banca_clientePERSONAL -0.561 0.574786
## mo_modalidadMV 3.210 0.001325
## mo_modalidadSV 3.323 0.000890
## mo_modalidadTV 2.097 0.036015
## Tipo_Factor_ExternoFactores Naturales - Volcán 1.038 0.299279
## Tipo_Factor_ExternoOla Invernal 6.894 5.41e-12
## Tipo_Factor_ExternoSequía 0.740 0.459249
## factor(Departamento_Inversion)Nariño -9.063 < 2e-16
## factor(Departamento_Inversion)Valle del cauca 4.962 6.96e-07
## factor(Departamento_Inversion)Valle del Cauca -0.651 0.515022
## factor(Departamento_Inversion)Other -0.768 0.442769
## generoMASCULINO 3.525 0.000424
## cuotas_pactadas -17.923 < 2e-16
## monto_desembolso -9.801 < 2e-16
## saldo 13.148 < 2e-16
## COMPARATIVO_OCURRENCIA_HECHONo reporta -2.935 0.003336
## COMPARATIVO_OCURRENCIA_HECHOV-D -0.163 0.870176
##
## (Intercept)
## tipo_de_productoCAP TRABAJO MUJER MICROEMPRESARIA .
## tipo_de_productoCAP. TRABAJO PROYECTO MICROCREDITO
## tipo_de_productoCAPITAL DE TRABAJO ORDINARIA FINAGRO .
## tipo_de_productoINV. VICTIMA CONFLICTO ARMADO INTERNO *
## tipo_de_productoINVERSION - COMP. ANIM.Y RETEN.VIENTRES ***
## tipo_de_productoINVERSION - PLANTACION Y MANTENIMIENTO **
## tipo_de_productoINVERSION MUJER MICROEMPRESARIA .
## tipo_de_productoINVERSIÓN MULTIDESTINO IBR
## tipo_de_productoINVERSION MULTIDESTINO MICRO
## tipo_de_productoINVERSION ORDINARIA FINAGRO **
## tipo_de_productoINVERSIÓN PROYECTO MICROCREDITO
## tipo_de_productoMICROCREDITO ECONOMIA POPULAR RP .
## tipo_de_productoNORMALIZACION DE RECURSOS FINAGRO IBR **
## tipo_de_productoOther .
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA SEMESTRAL ***
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA TRIMESTRAL ***
## tasa_referencialTASA Cero
## tasa_referencialTasa DTF Efectivo Anual ***
## tasa_referencialOther *
## tipo_productor_pmgGran Productor Finagro
## tipo_productor_pmgMediano Productor
## tipo_productor_pmgMicrofinanzas
## tipo_productor_pmgNo Agropecuario
## tipo_productor_pmgPequeño Productor
## destino_agrupadoAgricultura - cultivos
## destino_agrupadoComercializacion - transformacion agropecuaria *
## destino_agrupadoFinancieros - capital de trabajo
## destino_agrupadoInfraestructura - equipamiento *
## destino_agrupadoPecuaria - pesca
## destino_agrupadoServicio - apoyo agropecuario .
## Banca_clienteMICROFINANZAS
## Banca_clientePERSONAL
## mo_modalidadMV **
## mo_modalidadSV ***
## mo_modalidadTV *
## Tipo_Factor_ExternoFactores Naturales - Volcán
## Tipo_Factor_ExternoOla Invernal ***
## Tipo_Factor_ExternoSequía
## factor(Departamento_Inversion)Nariño ***
## factor(Departamento_Inversion)Valle del cauca ***
## factor(Departamento_Inversion)Valle del Cauca
## factor(Departamento_Inversion)Other
## generoMASCULINO ***
## cuotas_pactadas ***
## monto_desembolso ***
## saldo ***
## COMPARATIVO_OCURRENCIA_HECHONo reporta **
## COMPARATIVO_OCURRENCIA_HECHOV-D
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 29951 on 38818 degrees of freedom
## Residual deviance: 28682 on 38770 degrees of freedom
## AIC: 28780
##
## Number of Fisher Scoring iterations: 11
# Predecir probabilidades en test
prob_logit <- predict(model_logit, newdata = test_bin, type = "response")
# Construir curva ROC y calcular AUC
roc_obj <- roc(test_bin$target_binario, prob_logit,
levels = c("Al Día", "En Mora"), quiet = TRUE)
# Umbral óptimo por criterio de Youden (maximiza Sensibilidad + Especificidad)
best_thr <- as.numeric(coords(roc_obj, "best", ret = "threshold",
best.method = "youden")[1])
cat("\nUmbral óptimo (Youden):", round(best_thr, 4), "\n")##
## Umbral óptimo (Youden): 0.1479
# Matriz de confusión y métricas
cm_logit <- confusionMatrix(pred_logit, test_bin$target_binario,
positive = "En Mora")
print(cm_logit)## Confusion Matrix and Statistics
##
## Reference
## Prediction Al Día En Mora
## Al Día 10260 1045
## En Mora 4218 1112
##
## Accuracy : 0.6836
## 95% CI : (0.6765, 0.6907)
## No Information Rate : 0.8703
## P-Value [Acc > NIR] : 1
##
## Kappa : 0.1379
##
## Mcnemar's Test P-Value : <2e-16
##
## Sensitivity : 0.51553
## Specificity : 0.70866
## Pos Pred Value : 0.20863
## Neg Pred Value : 0.90756
## Prevalence : 0.12967
## Detection Rate : 0.06685
## Detection Prevalence : 0.32041
## Balanced Accuracy : 0.61210
##
## 'Positive' Class : En Mora
##
##
## AUC-ROC: 0.6493
## Accuracy: 0.6836
## Sensitivity: 0.5155
## Specificity: 0.7087
## Precision: 0.2086
## F1: 0.297
## Balanced Acc.: 0.6121
Dado el desbalance en la variable dependiente, se implementó un esquema de ponderación de clases con el objetivo de incrementar la importancia relativa de la clase minoritaria (“En Mora”).
##
## Proporciones reales en train:
##
## Al Día En Mora
## 0.8703 0.1297
prop_objetivo <- c("Al Día" = 0.55, "En Mora" = 0.45)
weights_class <- prop_objetivo / prop_real
cat("\nPesos por clase:\n")##
## Pesos por clase:
##
## Al Día En Mora
## 0.6320 3.4701
suppressWarnings(
model_logit_w <- glm(
target_binario ~ tipo_de_producto + tasa_referencial + tipo_productor_pmg +
destino_agrupado + Banca_cliente + mo_modalidad +
Tipo_Factor_Externo + Departamento_Inversion + genero +
cuotas_pactadas + monto_desembolso + saldo +
COMPARATIVO_OCURRENCIA_HECHO,
data = train_binw, # Dataset CON pesos
family = binomial(link = "logit"),
weights = w
)
)
summary(model_logit_w)##
## Call:
## glm(formula = target_binario ~ tipo_de_producto + tasa_referencial +
## tipo_productor_pmg + destino_agrupado + Banca_cliente + mo_modalidad +
## Tipo_Factor_Externo + Departamento_Inversion + genero + cuotas_pactadas +
## monto_desembolso + saldo + COMPARATIVO_OCURRENCIA_HECHO,
## family = binomial(link = "logit"), data = train_binw, weights = w)
##
## Coefficients:
## Estimate
## (Intercept) -13.25924
## tipo_de_productoCAP TRABAJO MUJER MICROEMPRESARIA -0.80721
## tipo_de_productoCAP. TRABAJO PROYECTO MICROCREDITO 0.19041
## tipo_de_productoCAPITAL DE TRABAJO ORDINARIA FINAGRO 3.81200
## tipo_de_productoINV. VICTIMA CONFLICTO ARMADO INTERNO 4.39589
## tipo_de_productoINVERSION - COMP. ANIM.Y RETEN.VIENTRES 5.64778
## tipo_de_productoINVERSION - PLANTACION Y MANTENIMIENTO 4.86298
## tipo_de_productoINVERSION MUJER MICROEMPRESARIA -0.94141
## tipo_de_productoINVERSIÓN MULTIDESTINO IBR 2.47621
## tipo_de_productoINVERSION MULTIDESTINO MICRO -0.40570
## tipo_de_productoINVERSION ORDINARIA FINAGRO 4.54943
## tipo_de_productoINVERSIÓN PROYECTO MICROCREDITO -0.57193
## tipo_de_productoMICROCREDITO ECONOMIA POPULAR RP -1.04977
## tipo_de_productoNORMALIZACION DE RECURSOS FINAGRO IBR 5.63337
## tipo_de_productoOther 4.34595
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA SEMESTRAL -3.50300
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA TRIMESTRAL -3.79276
## tasa_referencialTASA Cero 1.49841
## tasa_referencialTasa DTF Efectivo Anual -2.98337
## tasa_referencialOther 3.31411
## tipo_productor_pmgGran Productor Finagro 2.12569
## tipo_productor_pmgMediano Productor 12.25295
## tipo_productor_pmgMicrofinanzas 12.96461
## tipo_productor_pmgNo Agropecuario 12.22804
## tipo_productor_pmgPequeño Productor 12.77747
## destino_agrupadoAgricultura - cultivos -1.34469
## destino_agrupadoComercializacion - transformacion agropecuaria -2.00976
## destino_agrupadoFinancieros - capital de trabajo -0.88631
## destino_agrupadoInfraestructura - equipamiento -1.83285
## destino_agrupadoPecuaria - pesca -1.32445
## destino_agrupadoServicio - apoyo agropecuario -1.51270
## Banca_clienteMICROFINANZAS 0.05828
## Banca_clientePERSONAL -0.19703
## mo_modalidadMV 0.88253
## mo_modalidadSV 0.35155
## mo_modalidadTV 1.54759
## Tipo_Factor_ExternoFactores Naturales - Volcán 0.30368
## Tipo_Factor_ExternoOla Invernal 0.47705
## Tipo_Factor_ExternoSequía 0.03436
## Departamento_InversionNariño -0.33311
## Departamento_InversionValle del cauca 0.29355
## Departamento_InversionValle del Cauca -0.38815
## Departamento_InversionOther -0.42025
## generoMASCULINO 0.10574
## cuotas_pactadas -0.42037
## monto_desembolso -0.41840
## saldo 0.45948
## COMPARATIVO_OCURRENCIA_HECHONo reporta -0.33741
## COMPARATIVO_OCURRENCIA_HECHOV-D -0.03718
## Std. Error
## (Intercept) 65.67261
## tipo_de_productoCAP TRABAJO MUJER MICROEMPRESARIA 0.32141
## tipo_de_productoCAP. TRABAJO PROYECTO MICROCREDITO 0.40380
## tipo_de_productoCAPITAL DE TRABAJO ORDINARIA FINAGRO 1.12092
## tipo_de_productoINV. VICTIMA CONFLICTO ARMADO INTERNO 1.12578
## tipo_de_productoINVERSION - COMP. ANIM.Y RETEN.VIENTRES 1.15383
## tipo_de_productoINVERSION - PLANTACION Y MANTENIMIENTO 1.12570
## tipo_de_productoINVERSION MUJER MICROEMPRESARIA 0.32773
## tipo_de_productoINVERSIÓN MULTIDESTINO IBR 0.98810
## tipo_de_productoINVERSION MULTIDESTINO MICRO 0.37581
## tipo_de_productoINVERSION ORDINARIA FINAGRO 1.12471
## tipo_de_productoINVERSIÓN PROYECTO MICROCREDITO 0.41121
## tipo_de_productoMICROCREDITO ECONOMIA POPULAR RP 0.37928
## tipo_de_productoNORMALIZACION DE RECURSOS FINAGRO IBR 1.15492
## tipo_de_productoOther 1.09773
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA SEMESTRAL 0.30255
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA TRIMESTRAL 0.64869
## tasa_referencialTASA Cero 0.91935
## tasa_referencialTasa DTF Efectivo Anual 0.30830
## tasa_referencialOther 0.82953
## tipo_productor_pmgGran Productor Finagro 239.19722
## tipo_productor_pmgMediano Productor 65.66362
## tipo_productor_pmgMicrofinanzas 65.66540
## tipo_productor_pmgNo Agropecuario 65.66624
## tipo_productor_pmgPequeño Productor 65.66349
## destino_agrupadoAgricultura - cultivos 0.77117
## destino_agrupadoComercializacion - transformacion agropecuaria 0.83869
## destino_agrupadoFinancieros - capital de trabajo 0.76350
## destino_agrupadoInfraestructura - equipamiento 0.78495
## destino_agrupadoPecuaria - pesca 0.77205
## destino_agrupadoServicio - apoyo agropecuario 0.77144
## Banca_clienteMICROFINANZAS 0.18318
## Banca_clientePERSONAL 0.29843
## mo_modalidadMV 0.16828
## mo_modalidadSV 0.08984
## mo_modalidadTV 0.58427
## Tipo_Factor_ExternoFactores Naturales - Volcán 0.18767
## Tipo_Factor_ExternoOla Invernal 0.05380
## Tipo_Factor_ExternoSequía 0.13714
## Departamento_InversionNariño 0.02501
## Departamento_InversionValle del cauca 0.05124
## Departamento_InversionValle del Cauca 0.39904
## Departamento_InversionOther 0.39125
## generoMASCULINO 0.02150
## cuotas_pactadas 0.01896
## monto_desembolso 0.03106
## saldo 0.02554
## COMPARATIVO_OCURRENCIA_HECHONo reporta 0.07708
## COMPARATIVO_OCURRENCIA_HECHOV-D 0.07750
## z value Pr(>|z|)
## (Intercept) -0.202 0.839996
## tipo_de_productoCAP TRABAJO MUJER MICROEMPRESARIA -2.511 0.012024
## tipo_de_productoCAP. TRABAJO PROYECTO MICROCREDITO 0.472 0.637251
## tipo_de_productoCAPITAL DE TRABAJO ORDINARIA FINAGRO 3.401 0.000672
## tipo_de_productoINV. VICTIMA CONFLICTO ARMADO INTERNO 3.905 9.43e-05
## tipo_de_productoINVERSION - COMP. ANIM.Y RETEN.VIENTRES 4.895 9.84e-07
## tipo_de_productoINVERSION - PLANTACION Y MANTENIMIENTO 4.320 1.56e-05
## tipo_de_productoINVERSION MUJER MICROEMPRESARIA -2.873 0.004072
## tipo_de_productoINVERSIÓN MULTIDESTINO IBR 2.506 0.012209
## tipo_de_productoINVERSION MULTIDESTINO MICRO -1.080 0.280350
## tipo_de_productoINVERSION ORDINARIA FINAGRO 4.045 5.23e-05
## tipo_de_productoINVERSIÓN PROYECTO MICROCREDITO -1.391 0.164275
## tipo_de_productoMICROCREDITO ECONOMIA POPULAR RP -2.768 0.005644
## tipo_de_productoNORMALIZACION DE RECURSOS FINAGRO IBR 4.878 1.07e-06
## tipo_de_productoOther 3.959 7.52e-05
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA SEMESTRAL -11.578 < 2e-16
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA TRIMESTRAL -5.847 5.01e-09
## tasa_referencialTASA Cero 1.630 0.103132
## tasa_referencialTasa DTF Efectivo Anual -9.677 < 2e-16
## tasa_referencialOther 3.995 6.46e-05
## tipo_productor_pmgGran Productor Finagro 0.009 0.992909
## tipo_productor_pmgMediano Productor 0.187 0.851973
## tipo_productor_pmgMicrofinanzas 0.197 0.843488
## tipo_productor_pmgNo Agropecuario 0.186 0.852276
## tipo_productor_pmgPequeño Productor 0.195 0.845714
## destino_agrupadoAgricultura - cultivos -1.744 0.081213
## destino_agrupadoComercializacion - transformacion agropecuaria -2.396 0.016561
## destino_agrupadoFinancieros - capital de trabajo -1.161 0.245704
## destino_agrupadoInfraestructura - equipamiento -2.335 0.019544
## destino_agrupadoPecuaria - pesca -1.715 0.086254
## destino_agrupadoServicio - apoyo agropecuario -1.961 0.049893
## Banca_clienteMICROFINANZAS 0.318 0.750356
## Banca_clientePERSONAL -0.660 0.509101
## mo_modalidadMV 5.244 1.57e-07
## mo_modalidadSV 3.913 9.11e-05
## mo_modalidadTV 2.649 0.008078
## Tipo_Factor_ExternoFactores Naturales - Volcán 1.618 0.105620
## Tipo_Factor_ExternoOla Invernal 8.867 < 2e-16
## Tipo_Factor_ExternoSequía 0.251 0.802181
## Departamento_InversionNariño -13.317 < 2e-16
## Departamento_InversionValle del cauca 5.729 1.01e-08
## Departamento_InversionValle del Cauca -0.973 0.330704
## Departamento_InversionOther -1.074 0.282768
## generoMASCULINO 4.918 8.76e-07
## cuotas_pactadas -22.171 < 2e-16
## monto_desembolso -13.469 < 2e-16
## saldo 17.992 < 2e-16
## COMPARATIVO_OCURRENCIA_HECHONo reporta -4.377 1.20e-05
## COMPARATIVO_OCURRENCIA_HECHOV-D -0.480 0.631378
##
## (Intercept)
## tipo_de_productoCAP TRABAJO MUJER MICROEMPRESARIA *
## tipo_de_productoCAP. TRABAJO PROYECTO MICROCREDITO
## tipo_de_productoCAPITAL DE TRABAJO ORDINARIA FINAGRO ***
## tipo_de_productoINV. VICTIMA CONFLICTO ARMADO INTERNO ***
## tipo_de_productoINVERSION - COMP. ANIM.Y RETEN.VIENTRES ***
## tipo_de_productoINVERSION - PLANTACION Y MANTENIMIENTO ***
## tipo_de_productoINVERSION MUJER MICROEMPRESARIA **
## tipo_de_productoINVERSIÓN MULTIDESTINO IBR *
## tipo_de_productoINVERSION MULTIDESTINO MICRO
## tipo_de_productoINVERSION ORDINARIA FINAGRO ***
## tipo_de_productoINVERSIÓN PROYECTO MICROCREDITO
## tipo_de_productoMICROCREDITO ECONOMIA POPULAR RP **
## tipo_de_productoNORMALIZACION DE RECURSOS FINAGRO IBR ***
## tipo_de_productoOther ***
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA SEMESTRAL ***
## tasa_referencialINDICADOR BANCARIO DE REFERENCIA TRIMESTRAL ***
## tasa_referencialTASA Cero
## tasa_referencialTasa DTF Efectivo Anual ***
## tasa_referencialOther ***
## tipo_productor_pmgGran Productor Finagro
## tipo_productor_pmgMediano Productor
## tipo_productor_pmgMicrofinanzas
## tipo_productor_pmgNo Agropecuario
## tipo_productor_pmgPequeño Productor
## destino_agrupadoAgricultura - cultivos .
## destino_agrupadoComercializacion - transformacion agropecuaria *
## destino_agrupadoFinancieros - capital de trabajo
## destino_agrupadoInfraestructura - equipamiento *
## destino_agrupadoPecuaria - pesca .
## destino_agrupadoServicio - apoyo agropecuario *
## Banca_clienteMICROFINANZAS
## Banca_clientePERSONAL
## mo_modalidadMV ***
## mo_modalidadSV ***
## mo_modalidadTV **
## Tipo_Factor_ExternoFactores Naturales - Volcán
## Tipo_Factor_ExternoOla Invernal ***
## Tipo_Factor_ExternoSequía
## Departamento_InversionNariño ***
## Departamento_InversionValle del cauca ***
## Departamento_InversionValle del Cauca
## Departamento_InversionOther
## generoMASCULINO ***
## cuotas_pactadas ***
## monto_desembolso ***
## saldo ***
## COMPARATIVO_OCURRENCIA_HECHONo reporta ***
## COMPARATIVO_OCURRENCIA_HECHOV-D
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 53426 on 38818 degrees of freedom
## Residual deviance: 50907 on 38770 degrees of freedom
## AIC: 61530
##
## Number of Fisher Scoring iterations: 10
# 9e. Predicción sobre test real sin modificaciones ---
prob_logit_w <- predict(model_logit_w, newdata = test_bin, type = "response")
# 9f. Curva ROC ---
roc_obj_w <- roc(test_bin$target_binario, prob_logit_w,
levels = c("Al Día", "En Mora"), quiet = TRUE)
# 9g. Umbral óptimo por criterio de Youden ---
best_thr_w <- as.numeric(coords(roc_obj_w, "best", ret = "threshold",
best.method = "youden")[1])
cat("\nUmbral óptimo ponderado (Youden):", round(best_thr_w, 4), "\n")##
## Umbral óptimo ponderado (Youden): 0.4927
# 9h. Clasificación final ---
pred_logit_w <- factor(
ifelse(prob_logit_w > best_thr_w, "En Mora", "Al Día"),
levels = levels(test_bin$target_binario)
)# 9i. Evaluación ---
cm_logit_w <- confusionMatrix(pred_logit_w, test_bin$target_binario,
positive = "En Mora")
print(cm_logit_w)## Confusion Matrix and Statistics
##
## Reference
## Prediction Al Día En Mora
## Al Día 10572 1084
## En Mora 3906 1073
##
## Accuracy : 0.7
## 95% CI : (0.693, 0.707)
## No Information Rate : 0.8703
## P-Value [Acc > NIR] : 1
##
## Kappa : 0.1462
##
## Mcnemar's Test P-Value : <2e-16
##
## Sensitivity : 0.4975
## Specificity : 0.7302
## Pos Pred Value : 0.2155
## Neg Pred Value : 0.9070
## Prevalence : 0.1297
## Detection Rate : 0.0645
## Detection Prevalence : 0.2993
## Balanced Accuracy : 0.6138
##
## 'Positive' Class : En Mora
##
##
## AUC-ROC: 0.6493
## Accuracy: 0.7
## Sensitivity: 0.4975
## Specificity: 0.7302
## Precision: 0.2155
## F1: 0.3007
## Balanced Acc.: 0.6138
Es un modelo de clasificación que utiliza una estructura de árbol para tomar decisiones basadas en las características de los datos. Cada nodo del árbol representa una característica, cada rama representa un valor de esa característica y cada hoja representa una clase o resultado final. El árbol se construye dividiendo el conjunto de datos en subconjuntos basados en la característica que mejor separa las clases en cada paso. Es fácil de interpretar y visualizar, lo que lo hace popular para tareas de clasificación y regresión.
# Modelo de árbol de decisión sin ponderación
tree_model <- rpart(
target_binario ~ tipo_de_producto + tasa_referencial + tipo_productor_pmg +
destino_agrupado + Banca_cliente + mo_modalidad +
Tipo_Factor_Externo + Departamento_Inversion + genero +
cuotas_pactadas + monto_desembolso + saldo +
COMPARATIVO_OCURRENCIA_HECHO,
data = train_bin, # Dataset SIN pesos
method = "class",
control = rpart.control(cp = 0.01)
)El árbol de decisión muestra que la variable más determinante para clasificar el riesgo crediticio es el saldo, ya que realiza la primera división separando a los clientes con mayor probabilidad de mora de aquellos con menor riesgo. En particular, valores bajos de saldo se asocian con una alta probabilidad de incumplimiento, formando un segmento pequeño pero crítico. Para el resto de la población, el modelo utiliza variables como el número de cuotas pactadas y el tipo de producto para refinar la clasificación, identificando subgrupos mayoritariamente “Al Día” pero también algunos nichos específicos con riesgo elevado. En conjunto, el árbol evidencia que el riesgo no es uniforme, sino que depende de combinaciones específicas de variables, permitiendo detectar tanto grupos masivos de bajo riesgo como segmentos reducidos con alta probabilidad de mora.
prob_tree <- predict(tree_model, newdata = test_bin, type = "prob")[, "En Mora"]
roc_tree <- roc(test_bin$target_binario, prob_tree,
levels = c("Al Día", "En Mora"), quiet = TRUE)
best_thr_tree <- as.numeric(coords(roc_tree, "best", ret = "threshold",
best.method = "youden")[1])
cat("\nUmbral óptimo árbol sin pesos (Youden):", round(best_thr_tree, 4), "\n")##
## Umbral óptimo árbol sin pesos (Youden): 0.1546
## Confusion Matrix and Statistics
##
## Reference
## Prediction Al Día En Mora
## Al Día 14222 1885
## En Mora 256 272
##
## Accuracy : 0.8713
## 95% CI : (0.8661, 0.8763)
## No Information Rate : 0.8703
## P-Value [Acc > NIR] : 0.3612
##
## Kappa : 0.1598
##
## Mcnemar's Test P-Value : <2e-16
##
## Sensitivity : 0.12610
## Specificity : 0.98232
## Pos Pred Value : 0.51515
## Neg Pred Value : 0.88297
## Prevalence : 0.12967
## Detection Rate : 0.01635
## Detection Prevalence : 0.03174
## Balanced Accuracy : 0.55421
##
## 'Positive' Class : En Mora
##
##
## AUC-ROC: 0.555
## Accuracy: 0.8713
## Sensitivity: 0.1261
## Specificity: 0.9823
## Precision: 0.5152
## F1: 0.2026
## Balanced Acc.: 0.5542
tree_model_w <- rpart(
target_binario ~ tipo_de_producto + tasa_referencial + tipo_productor_pmg +
destino_agrupado + Banca_cliente + mo_modalidad +
Tipo_Factor_Externo + Departamento_Inversion + genero +
cuotas_pactadas + monto_desembolso + saldo +
COMPARATIVO_OCURRENCIA_HECHO,
data = train_binw, # Dataset CON pesos
method = "class",
weights = w, # Vector de pesos por observación
control = rpart.control(cp = 0.01)
)prob_tree_w <- predict(tree_model_w, newdata = test_bin, type = "prob")[, "En Mora"]
roc_tree_w <- roc(test_bin$target_binario, prob_tree_w,
levels = c("Al Día", "En Mora"), quiet = TRUE)
best_thr_tree_w <- as.numeric(coords(roc_tree_w, "best", ret = "threshold",
best.method = "youden")[1])
cat("\nUmbral óptimo árbol ponderado (Youden):", round(best_thr_tree_w, 4), "\n")##
## Umbral óptimo árbol ponderado (Youden): 0.5233
cm_tree_w <- confusionMatrix(pred_tree_w, test_bin$target_binario, positive = "En Mora")
print(cm_tree_w)## Confusion Matrix and Statistics
##
## Reference
## Prediction Al Día En Mora
## Al Día 12781 1573
## En Mora 1697 584
##
## Accuracy : 0.8034
## 95% CI : (0.7973, 0.8094)
## No Information Rate : 0.8703
## P-Value [Acc > NIR] : 1.00000
##
## Kappa : 0.1499
##
## Mcnemar's Test P-Value : 0.03148
##
## Sensitivity : 0.27075
## Specificity : 0.88279
## Pos Pred Value : 0.25603
## Neg Pred Value : 0.89041
## Prevalence : 0.12967
## Detection Rate : 0.03511
## Detection Prevalence : 0.13712
## Balanced Accuracy : 0.57677
##
## 'Positive' Class : En Mora
##
##
## AUC-ROC: 0.5779
## Accuracy: 0.8034
## Sensitivity: 0.2707
## Specificity: 0.8828
## Precision: 0.256
## F1: 0.2632
## Balanced Acc.: 0.5768
# ── ELIMINAR VARIABLES CON LEAKAGE DE LAS BASES DE ENTRENAMIENTO Y TEST ──────
# dias_vencido ES el target en forma numérica — su presencia causa AUC = 1.0
# rango es la categorización directa de dias_vencido — también leakage
vars_leakage <- c("dias_vencido", "rango")
train_bin <- train_bin[, !names(train_bin) %in% vars_leakage]
test_bin <- test_bin[, !names(test_bin) %in% vars_leakage]
train_binw <- train_binw[, !names(train_binw) %in% vars_leakage]XGBoost es un algoritmo de aprendizaje automático basado en árboles de decisión que utiliza el método de boosting para mejorar la precisión de las predicciones. Es especialmente efectivo para problemas de clasificación y regresión, y es conocido por su eficiencia computacional y capacidad para manejar grandes conjuntos de datos con características mixtas (numéricas y categóricas). XGBoost construye modelos secuenciales donde cada nuevo árbol corrige los errores del anterior, lo que resulta en un modelo final robusto y preciso.
# Variables predictoras sin target, rango ni w
vars_xgb <- setdiff(names(train_bin), c("target_binario", "rango"))
# Matrices de features
X_train <- model.matrix(~ . - 1, data = train_bin[, vars_xgb])
X_test <- model.matrix(~ . - 1, data = test_bin[, vars_xgb])
# Alinear columnas: test puede no tener todos los niveles de train
cols_comunes <- intersect(colnames(X_train), colnames(X_test))
X_train <- X_train[, cols_comunes]
X_test <- X_test[, cols_comunes]
# Targets numéricos: "En Mora" = 1, "Al Día" = 0
y_train <- as.numeric(train_bin$target_binario == "En Mora")
y_test <- as.numeric(test_bin$target_binario == "En Mora")dtrain <- xgb.DMatrix(data = X_train, label = y_train)
dtest <- xgb.DMatrix(data = X_test, label = y_test)
xgb_model <- xgb.train(
params = params_xgb,
data = dtrain,
nrounds = 800,
watchlist = list(train = dtrain, test = dtest),
early_stopping_rounds = 20,
verbose = 0
)## Warning in throw_err_or_depr_msg("Parameter '", match_old, "' has been renamed
## to '", : Parameter 'watchlist' has been renamed to 'evals'. This warning will
## become an error in a future version.
prob_xgb <- predict(xgb_model, newdata = dtest)
roc_xgb <- roc(test_bin$target_binario, prob_xgb,
levels = c("Al Día", "En Mora"), quiet = TRUE)
best_thr_xgb <- as.numeric(coords(roc_xgb, "best", ret = "threshold",
best.method = "youden")[1])
cat("Umbral óptimo XGBoost sin pesos (Youden):", round(best_thr_xgb, 4), "\n")## Umbral óptimo XGBoost sin pesos (Youden): 0.1311
## Confusion Matrix and Statistics
##
## Reference
## Prediction Al Día En Mora
## Al Día 11465 800
## En Mora 3013 1357
##
## Accuracy : 0.7708
## 95% CI : (0.7643, 0.7772)
## No Information Rate : 0.8703
## P-Value [Acc > NIR] : 1
##
## Kappa : 0.2931
##
## Mcnemar's Test P-Value : <2e-16
##
## Sensitivity : 0.62911
## Specificity : 0.79189
## Pos Pred Value : 0.31053
## Neg Pred Value : 0.93477
## Prevalence : 0.12967
## Detection Rate : 0.08157
## Detection Prevalence : 0.26270
## Balanced Accuracy : 0.71050
##
## 'Positive' Class : En Mora
##
##
## AUC-ROC: 0.7689
## Accuracy: 0.7708
## Sensitivity: 0.6291
## Specificity: 0.7919
## Precision: 0.3105
## F1: 0.4158
## Balanced Acc.: 0.7105
# Preparar matriz desde train_binw (excluir target, rango y w)
vars_xgb_w <- setdiff(names(train_binw), c("target_binario", "rango", "w"))
X_train_w <- model.matrix(~ . - 1, data = train_binw[, vars_xgb_w])
# Alinear columnas con X_test
cols_comunes_w <- intersect(colnames(X_train_w), colnames(X_test))
X_train_w <- X_train_w[, cols_comunes_w]
X_test_w <- X_test[, cols_comunes_w]
y_train_w <- as.numeric(train_binw$target_binario == "En Mora")
# DMatrix CON pesos por observación
dtrain_w <- xgb.DMatrix(data = X_train_w,
label = y_train_w,
weight = train_binw$w) # <-- pesos explícitos
dtest_w <- xgb.DMatrix(data = X_test_w, label = y_test)xgb_model_w <- xgb.train(
params = params_xgb,
data = dtrain_w,
nrounds = 800,
watchlist = list(train = dtrain_w, test = dtest_w),
early_stopping_rounds = 20,
verbose = 0
)## Warning in throw_err_or_depr_msg("Parameter '", match_old, "' has been renamed
## to '", : Parameter 'watchlist' has been renamed to 'evals'. This warning will
## become an error in a future version.
prob_xgb_w <- predict(xgb_model_w, newdata = dtest_w)
roc_xgb_w <- roc(test_bin$target_binario, prob_xgb_w,
levels = c("Al Día", "En Mora"), quiet = TRUE)
best_thr_xgb_w <- as.numeric(coords(roc_xgb_w, "best", ret = "threshold",
best.method = "youden")[1])
cat("Umbral óptimo XGBoost ponderado (Youden):", round(best_thr_xgb_w, 4), "\n")## Umbral óptimo XGBoost ponderado (Youden): 0.4509
cm_xgb_w <- confusionMatrix(pred_xgb_w, test_bin$target_binario, positive = "En Mora")
print(cm_xgb_w)## Confusion Matrix and Statistics
##
## Reference
## Prediction Al Día En Mora
## Al Día 11753 780
## En Mora 2725 1377
##
## Accuracy : 0.7893
## 95% CI : (0.783, 0.7955)
## No Information Rate : 0.8703
## P-Value [Acc > NIR] : 1
##
## Kappa : 0.3253
##
## Mcnemar's Test P-Value : <2e-16
##
## Sensitivity : 0.63839
## Specificity : 0.81178
## Pos Pred Value : 0.33569
## Neg Pred Value : 0.93776
## Prevalence : 0.12967
## Detection Rate : 0.08278
## Detection Prevalence : 0.24659
## Balanced Accuracy : 0.72509
##
## 'Positive' Class : En Mora
##
##
## AUC-ROC: 0.7921
## Accuracy: 0.7893
## Sensitivity: 0.6384
## Specificity: 0.8118
## Precision: 0.3357
## F1: 0.44
## Balanced Acc.: 0.7251
En este apartado se presenta una tabla comparativa que resume las métricas clave de desempeño para cada uno de los modelos evaluados: Logit sin pesos, Logit ponderado, Árbol sin pesos, Árbol ponderado, XGBoost sin pesos y XGBoost ponderado. Las métricas incluidas son AUC-ROC, Accuracy, Sensitivity, Specificity, Precision, F1 Score y Balanced Accuracy. Esta tabla permite una comparación directa entre los modelos para identificar cuál ofrece el mejor rendimiento en la predicción del riesgo de incumplimiento crediticio.
tabla_completa <- data.frame(
Modelo = c(
"Logit sin pesos",
"Logit ponderado",
"Árbol sin pesos",
"Árbol ponderado",
"XGBoost sin pesos",
"XGBoost ponderado"
),
AUC = c(
round(auc(roc_obj), 4),
round(auc(roc_obj_w), 4),
round(auc(roc_tree), 4),
round(auc(roc_tree_w), 4),
round(auc(roc_xgb), 4),
round(auc(roc_xgb_w), 4)
),
Accuracy = c(
round(cm_logit$overall["Accuracy"], 4),
round(cm_logit_w$overall["Accuracy"], 4),
round(cm_tree$overall["Accuracy"], 4),
round(cm_tree_w$overall["Accuracy"], 4),
round(cm_xgb$overall["Accuracy"], 4),
round(cm_xgb_w$overall["Accuracy"], 4)
),
Sensitivity = c(
round(cm_logit$byClass["Sensitivity"], 4),
round(cm_logit_w$byClass["Sensitivity"], 4),
round(cm_tree$byClass["Sensitivity"], 4),
round(cm_tree_w$byClass["Sensitivity"], 4),
round(cm_xgb$byClass["Sensitivity"], 4),
round(cm_xgb_w$byClass["Sensitivity"], 4)
),
Specificity = c(
round(cm_logit$byClass["Specificity"], 4),
round(cm_logit_w$byClass["Specificity"], 4),
round(cm_tree$byClass["Specificity"], 4),
round(cm_tree_w$byClass["Specificity"], 4),
round(cm_xgb$byClass["Specificity"], 4),
round(cm_xgb_w$byClass["Specificity"], 4)
),
Precision = c(
round(cm_logit$byClass["Precision"], 4),
round(cm_logit_w$byClass["Precision"], 4),
round(cm_tree$byClass["Precision"], 4),
round(cm_tree_w$byClass["Precision"], 4),
round(cm_xgb$byClass["Precision"], 4),
round(cm_xgb_w$byClass["Precision"], 4)
),
F1 = c(
round(cm_logit$byClass["F1"], 4),
round(cm_logit_w$byClass["F1"], 4),
round(cm_tree$byClass["F1"], 4),
round(cm_tree_w$byClass["F1"], 4),
round(cm_xgb$byClass["F1"], 4),
round(cm_xgb_w$byClass["F1"], 4)
),
Balanced_Acc = c(
round(cm_logit$byClass["Balanced Accuracy"], 4),
round(cm_logit_w$byClass["Balanced Accuracy"], 4),
round(cm_tree$byClass["Balanced Accuracy"], 4),
round(cm_tree_w$byClass["Balanced Accuracy"], 4),
round(cm_xgb$byClass["Balanced Accuracy"], 4),
round(cm_xgb_w$byClass["Balanced Accuracy"], 4)
)
)
print(tabla_completa)## Modelo AUC Accuracy Sensitivity Specificity Precision F1
## 1 Logit sin pesos 0.6493 0.6836 0.5155 0.7087 0.2086 0.2970
## 2 Logit ponderado 0.6493 0.7000 0.4975 0.7302 0.2155 0.3007
## 3 Árbol sin pesos 0.5550 0.8713 0.1261 0.9823 0.5152 0.2026
## 4 Árbol ponderado 0.5779 0.8034 0.2707 0.8828 0.2560 0.2632
## 5 XGBoost sin pesos 0.7689 0.7708 0.6291 0.7919 0.3105 0.4158
## 6 XGBoost ponderado 0.7921 0.7893 0.6384 0.8118 0.3357 0.4400
## Balanced_Acc
## 1 0.6121
## 2 0.6138
## 3 0.5542
## 4 0.5768
## 5 0.7105
## 6 0.7251
plot(roc_obj, col = "steelblue", lwd = 2,
main = "Curvas ROC — Comparativa General")
plot(roc_obj_w, col = "steelblue", lwd = 2, lty = 2, add = TRUE)
plot(roc_tree, col = "forestgreen", lwd = 2, add = TRUE)
plot(roc_tree_w, col = "forestgreen", lwd = 2, lty = 2, add = TRUE)
plot(roc_xgb, col = "tomato", lwd = 2, add = TRUE)
plot(roc_xgb_w, col = "tomato", lwd = 2, lty = 2, add = TRUE)
abline(a = 0, b = 1, lty = 3, col = "gray60")
legend("bottomright",
legend = c(
paste0("Logit sin pesos (AUC = ", round(auc(roc_obj), 3), ")"),
paste0("Logit ponderado (AUC = ", round(auc(roc_obj_w), 3), ")"),
paste0("Árbol sin pesos (AUC = ", round(auc(roc_tree), 3), ")"),
paste0("Árbol ponderado (AUC = ", round(auc(roc_tree_w), 3), ")"),
paste0("XGBoost sin pesos (AUC = ", round(auc(roc_xgb), 3), ")"),
paste0("XGBoost ponderado (AUC = ", round(auc(roc_xgb_w), 3), ")")
),
col = c("steelblue","steelblue","forestgreen","forestgreen","tomato","tomato"),
lty = c(1, 2, 1, 2, 1, 2),
lwd = 2, bty = "n", cex = 0.82)