Data & ML
Caso de estudioScoring de mora temprana
El score legacy llegaba tarde. Tesorería veía el riesgo cuando la cuenta ya estaba en mora dura, y el costo de no cobro superaba el de un falso positivo.
+18% recall
en clientes en riesgo a 30 DPD vs. el score legacy
- #MachineLearning
- #SQL
- #ScikitLearn
- #CreditRisk
El trabajo no fue cambiar un algoritmo por otro más nuevo. Fue redefinir el momento de la decisión: detectar el roll a 30 DPD con una lista que operaciones pudiera ejecutar esa misma semana.
Construí el dataset sobre snapshots mensuales, no sobre un dump estático. Las window functions y los CTEs dejaron el roll-rate explícito. El modelo —HistGradientBoosting— se calibró contra un costo de negocio, no contra accuracy de notebook.
El entregable fue una ranking list + umbral documentado. El disclaimer forma parte del producto: sin reentrenamiento trimestral, el recall se come la estacionalidad.
- Problema
- El modelo vigente perdía casos de alto riesgo. Tesorería no tenía una lista priorizada y el costo de no cobro superaba el de los falsos positivos.
- Solución & pipeline
- SQL avanzado con CTEs y window functions sobre snapshots mensuales, features de roll-rate y HistGradientBoosting en Scikit-learn, con umbral calibrado por costo de negocio.
- Límite / alcance
- Validado para carteras con estacionalidad relativamente fija. Requiere reentrenamiento trimestral y no cubre productos revolving sin 6+ meses de historia.
SQL
WITH snapshots AS (
SELECT client_id, snapshot_date, days_past_due,
LAG(days_past_due) OVER (
PARTITION BY client_id
ORDER BY snapshot_date
) AS prev_dpd
FROM credit_monthly_snapshot
)
SELECT client_id, snapshot_date
FROM snapshots
WHERE days_past_due >= 30
AND COALESCE(prev_dpd, 0) < 30;