Propuesta de Credit Scoring: Optimizando la Toma de Decisiones Basada en Datos.
“Transformamos datos complejos en decisiones de negocio rentables.”
¿Qué es y cómo funciona?: Transformación de datos en probabilidades matemáticas de impago.
Componentes clave: Selección de variables, asignación de pesos (WoE) y escalamiento de puntos.
Un modelo no es estático; requiere un marco de control para asegurar su vigencia.
Zona Verde
Aprobación Automática El cliente supera el puntaje de seguridad.
Zona Amarilla
A Criterio del Especialista El cliente minimamente cumple con las condiciones (casos fronterizos).
Zona Roja
Rechazo Automático El riesgo excede las políticas de la institución.
Situación Actual
Crecimiento exponencial de solicitudes.
Necesidad de decisiones en tiempo real.
Competencia de fintechs y bancos digitales.
Regulaciones cada vez más exigentes.
Oportunidad
Datos históricos disponibles
Capacidad de cómputo moderna
Cultura de data analytics en evolución
A diferencia de modelos abstractos (“cajas negras”), nuestra metodología se basa en estadística clásica robusta.
La regresión logística mide la relación entre una o más variables independientes y la variable dependiente categórica mediante la estimación de probabilidades a través de una función logística.
\[ \ln\left(\frac{P(X)}{1 - P(X)}\right) = \beta_0 + \beta_1x_1 + \dots + \beta_nx_n \]
El puntaje final es la suma de pesos específicos asignados a variables clave:
| Categoría | Variables Críticas |
|---|---|
| Ratio de Liquidez Corriente | Capacidad de pagar deudas de corto plazo con sus activos líquidos. |
| Apalancamiento (Deuda/Patrimonio) | Qué tan endeudada está la empresa respecto a lo que poseen los dueños. |
| Comportamiento | Historial en Buró, puntualidad, créditos abiertos. |
# resumen IV y WoE por variable
lapply(
X = vars,
FUN = (iv, woe),
dt = dt_sets$dt_train,
y = 'status'
) -> predict_summ
names(predict_summ) <- vars
print(predict_summ)
## |variable |breaks | woe| total_iv|
## |:--------------|:--------------|-------:|--------:|
## |prom_saldo |missing | 1.402| 2.216|
## |prom_saldo |[0, 100) | 1.369| 2.216|
## |prom_saldo |[100, 200] | -1.204| 2.216|
## |prom_saldo |[200, 200<=x) | -1.102| 2.216|
## |prom_dep |missing | 1.607| 1.801|
## |prom_dep |28.5 | 0.296| 1.801|
## |prom_dep |182 | -1.551| 1.801|
## |nro_moras_obs |1 | -0.636| 0.309|
## |nro_moras_obs |2 | 0.386| 0.309|Cada variable es filtrada por su Poder Predictivo (IV) y su Fuerza de Evidencia (WoE).
Tenemos el Modelo Logístico:
\[ \ln\left(\frac{P(X)}{1 - P(X)}\right) = \beta_0 + \beta_1x_1 + \dots + \beta_nx_n \] Conformado por:
# construccion del modelo logistico
set.seed(123)
glm(
status ~ .,
family = binomial(link = 'logit'),
data = dt_woe$dt_train
) -> logit_model
summ(logit_model, model.info = FALSE)
## MODEL FIT:
## χ²(5) = 42585.49, p = 0.00
## Pseudo-R² (Cragg-Uhler) = 0.39
## Pseudo-R² (McFadden) = 0.29
## AIC = 106387.41, BIC = 106446.88
##
## Standard errors: MLE
## -------------------------------------------------------
## Est. S.E. z val. p
## ------------------------ ------- ------ -------- ------
## (Intercept) -0.74 0.01 -74.34 0.00
## prom_saldo 0.80 0.04 21.26 0.00
## prom_dep 0.75 0.04 19.38 0.00
## nro_moras_obs 0.81 0.01 57.70 0.00
## -------------------------------------------------------Una vez entrenado, el modelo se somete a una prueba de “estrés” utilizando el set de datos de prueba (20% - 30% del total), verificando su capacidad de generalización.
| Métrica | Cálculo |
|---|---|
| Precisión | \(\frac{VP}{VP + FP}\) |
| Recall | \(\frac{VP}{VP + FN}\) |
| F1-Score | \(\frac{2 \cdot P \cdot R}{P + R}\) |
# metricas
threshold = 0.181
mapply(
function(x,y){
perf_eva(
pred = x,
label = as.numeric(as.character(y$status)),
confusion_matrix = TRUE,
threshold = threshold,
show_plot = FALSE
)
},
predict_model, dt_woe, SIMPLIFY = F
) -> metrics
# matriz de confusión
metrics$dt_test$confusion_matrix
## $dat
## label pred_0 pred_1 error
## 1: 0 44434 19041 0.2999764
## 2: 1 44 290 0.1317365
## 3: total 44478 19331 0.2990957
# precisión, recall, media armónica entre presición y recall
accuracy.meas(
response = dt_woe$dt_test$status,
predicted = predict_model$dt_test,
threshold = threshold
)
##
## Call:
## accuracy.meas(response = dt_woe$dt_test$status, predicted = predict_model$dt_test,
## threshold = threshold)
##
## Examples are labelled as positive when predicted is greater than 0.181
##
## precision: 0.015
## recall: 0.868
## F: 0.015
# otras métricas
metrics$dt_test$binomial_metric
## $dat
## MSE RMSE LogLoss R2 KS AUC Gini
## 1: 0.08437658 0.2904765 0.2693769 -15.20454 0.6084199 0.8592149 0.7184298Para el esquema de negocio que se desea proponer se requiere de un modelo dinámico que sea capaz no solo de mitigar el riesgo al momento del otorgamiento del crédito, si no que también permitá la segmentación por niveles de riesgo y valor. Para ello se propone integrar un complemento al modelo que cumpla la misión de evaluar el comportamiento de pago crediticio, logrando segmentar a clientes en función de su desempeño y permitir “subir” o “bajar” niveles previamente establecidos.
Fase 1: Scoring de Admisión (Modelo Logístico): Determina la probabilidad de incumplimiento inicial para decidir el otorgamiento del crédito.
Fase 2: Scoring de Comportamiento (Behavioral Engine): Un modelo recurrente que recalibra el puntaje del cliente basado en su actividad reciente.
Sinergia: La combinación de ambos genera el Score Maestro, el cual ubica al cliente en categorías de gestión específicas.
Scorecard Model Banplus - Vikua