Todos los proyectos

Data & ML

Caso de estudio

Scoring 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;