Jesusrodriguezf90's picture
docs: actualizar Model Card con métricas reales, pipeline correcto y demo
2e1b074 verified
|
Raw
History Blame Contribute Delete
9.21 kB
metadata
language:
  - es
license: other
library_name: scikit-learn
tags:
  - tabular-classification
  - healthcare
  - diabetes
  - lightgbm
  - scikit-learn
  - predictive-modeling
  - shap
  - brfss
datasets:
  - Jesusrodriguezf90/brfss2015-diabetes-detection
metrics:
  - roc_auc
  - recall
  - f1
pipeline_tag: tabular-classification

LightGBM — Detección Temprana de Riesgo de Diabetes

Modelo de clasificación binaria para detección temprana de riesgo de diabetes desarrollado como Trabajo de Fin de Máster (TFM) en el Máster en Data Science de KSchool (2025–2026).

Pipeline sklearn completo: preprocesamiento determinista + ColumnTransformer + clasificador LightGBM, entrenado sobre 257.709 observaciones clínicas autorreportadas con 22 variables del cuestionario BRFSS 2015 (CDC).

Repositorio: TFM — GitHub
Demo interactiva: diabetes-risk-demo — HF Spaces


Métricas

Resultados de validación cruzada estratificada (5 folds) sobre el conjunto de entrenamiento:

Modelo ROC-AUC (CV media) PRC-AUC (CV media) ROC-AUC (CV std)
Random Forest 0.836 0.378 0.0018
XGBoost 0.837 0.384 0.0022
LightGBM ✓ 0.839 0.391 0.0017

Resultados sobre el conjunto de test (threshold=0.4733, F2-score óptimo en validación):

Métrica Valor
ROC-AUC 0.839
PRC-AUC 0.391
Recall 0.813
Precision 0.256

LightGBM se seleccionó como modelo final por ofrecer el mejor equilibrio entre ROC-AUC, PRC-AUC y recall en un contexto clínico desbalanceado. El threshold de 0.4733 maximiza el F2-score en validación (β=2), priorizando el recall sobre la precisión — en cribado clínico un falso negativo tiene un coste sanitario mucho mayor que un falso positivo.

Matriz de confusión (test, threshold=0.4733)

Predicho: No riesgo Predicho: Riesgo
Real: No riesgo 32.444 (TN) 13.420 (FP)
Real: Riesgo 1.063 (FN) 4.615 (TP)

Uso

import sys
import types
import numpy as np
import pandas as pd
import joblib
from huggingface_hub import hf_hub_download

# 1. Registrar el módulo src — necesario para deserializar el pipeline
#    El pkl fue serializado con src.preprocessing.preprocessing_pipeline

BINARY_VARS = [
    "BPMEDS", "BLOODCHO", "HAVARTH3", "QLACTLM2", "USEEQUIP",
    "BLIND", "DECIDE", "DIFFWALK", "DIFFALON", "DIFFDRES",
    "SMOKE100", "ADDEPEV2", "SEX",
]
CATEGORICAL_NOMINAL = ["BPHIGH4", "_RACE"]

def boosting_deterministic_preproc(X_input):
    X = X_input.copy()
    X = X.replace(-1, np.nan)
    for col in BINARY_VARS:
        if col in X.columns:
            X[col] = (X[col] == 1).astype(int)
    for col in CATEGORICAL_NOMINAL:
        if col in X.columns:
            X[col] = X[col].astype("category")
    return X

def cap_outliers_numeric(X_input, numeric_vars):
    X = X_input.copy()
    for col in numeric_vars:
        low = np.nanpercentile(X[col], 1)
        high = np.nanpercentile(X[col], 99)
        X[col] = X[col].clip(low, high)
    return X

src_mod = types.ModuleType("src")
preprocessing_mod = types.ModuleType("src.preprocessing")
pipeline_mod = types.ModuleType("src.preprocessing.preprocessing_pipeline")
pipeline_mod.boosting_deterministic_preproc = boosting_deterministic_preproc
pipeline_mod.cap_outliers_numeric = cap_outliers_numeric
src_mod.preprocessing = preprocessing_mod
preprocessing_mod.preprocessing_pipeline = pipeline_mod
sys.modules.setdefault("src", src_mod)
sys.modules.setdefault("src.preprocessing", preprocessing_mod)
sys.modules.setdefault("src.preprocessing.preprocessing_pipeline", pipeline_mod)

# 2. Descargar y cargar el pipeline
ruta = hf_hub_download(
    repo_id="Jesusrodriguezf90/lgbm-diabetes-early-detection",
    filename="lgbm_diabetes_pipeline.pkl"
)
pipeline = joblib.load(ruta)

# 3. Preparar datos de entrada
#    X debe ser un DataFrame con las 22 variables del BRFSS 2015
#    en su codificación original (valores enteros según el codebook del CDC)
X = pd.DataFrame([{
    "GENHLTH": 3, "BPHIGH4": 3, "BPMEDS": 2, "BLOODCHO": 1,
    "HAVARTH3": 2, "ADDEPEV2": 2, "SEX": 1, "QLACTLM2": 2,
    "USEEQUIP": 2, "BLIND": 2, "DECIDE": 2, "DIFFWALK": 2,
    "DIFFDRES": 2, "DIFFALON": 2, "SMOKE100": 2, "EXEROFT1": 3.0,
    "_RACE": 1, "_AGEG5YR": 7, "_BMI5CAT": 2,
    "_FRUTSUM": 1.0, "_VEGESUM": 2.0, "_PACAT1": 2,
}])

# 4. Inferencia con threshold dinámico
proba = pipeline.predict_proba(X)[0][1]
threshold = 0.4733  # threshold por defecto — ajustable según contexto asistencial
decision = "Realizar prueba HbA1c" if proba >= threshold else "No realizar prueba HbA1c"

print(f"Probabilidad estimada de riesgo: {proba * 100:.1f}%")
print(f"Decisión (threshold={threshold}): {decision}")

Arquitectura y entrenamiento

Pipeline sklearn

El pipeline encapsula todas las transformaciones para garantizar ausencia de data leakage:

Step Componente Descripción
1 FunctionTransformer Preprocesamiento determinista: reemplaza -1 por NaN, normaliza binarias a 0/1, fuerza tipo category en nominales
2 ColumnTransformer Imputación (moda / mediana) + capping de outliers (P1-P99) + encoding nativo para boosting
3 LGBMClassifier Clasificador final con codificación nativa de categóricas

Selección de threshold

El threshold óptimo se determina maximizando el F2-score (β=2) sobre la curva Precision–Recall del conjunto de validación. Con β=2, el recall tiene cuatro veces más peso que la precisión — refleja el coste clínico asimétrico donde un falso negativo (diabetes no detectada) genera un coste estimado de ~2.817€/paciente/año, frente a ~30€ de una prueba HbA1c innecesaria.

El pipeline soporta threshold dinámico (rango 0.10–0.90) para que el profesional sanitario pueda ajustar la sensibilidad según la capacidad asistencial disponible.

Parámetros de entrenamiento

Parámetro Valor
Dataset BRFSS 2015 (CDC)
Observaciones 257.709
Variables de entrada 22 (clínicas y demográficas)
Split 60% train / 20% val / 20% test — estratificado
Tamaño conjunto test 51.542 individuos
Validación cruzada 5 folds estratificados sobre train
Desbalance clase positiva Tratado con class_weight en LightGBM
Threshold por defecto 0.4733 (F2-score óptimo en validación)
random_state 42
Hardware Google Colab (CPU)

Interpretabilidad

El modelo incluye análisis de interpretabilidad con Feature Importance y SHAP (SHapley Additive exPlanations), que permite explicar tanto el comportamiento global del modelo como predicciones individuales.

Las variables con mayor influencia sobre el riesgo de diabetes identificadas por el modelo:

Variable Importancia Interpretación clínica
_VEGESUM 1143 Total porciones de vegetales diarias
_FRUTSUM 917 Total porciones de frutas diarias
_AGEG5YR 712 Edad en grupos de 5 años
EXEROFT1 617 Frecuencia de ejercicio semanal
GENHLTH 477 Estado general de salud autorreportado
_BMI5CAT 358 Categoría de IMC

La demo interactiva incluye un gráfico SHAP waterfall individual que explica en tiempo real qué variables aumentaron o redujeron el riesgo para cada predicción concreta.


Limitaciones

  • Entrenado sobre datos del BRFSS 2015 (población estadounidense) — puede no generalizar directamente a otras poblaciones sin recalibración
  • Precision baja (0.256) con threshold=0.4733 — diseño deliberado para maximizar recall en cribado; genera falsos positivos asumibles dado el bajo coste de la prueba HbA1c confirmatoria
  • Las 22 variables son autorreportadas — sujetas a sesgo de respuesta del encuestado
  • El modelo es un apoyo al cribado y no reemplaza el diagnóstico médico; la decisión clínica final corresponde siempre al profesional sanitario
  • Sin datos de seguimiento longitudinal — no predice progresión ni complicaciones

Dataset

BRFSS 2015 — Behavioral Risk Factor Surveillance System
Centers for Disease Control and Prevention (CDC), Estados Unidos
🔗 CDC BRFSS 2015

  • 257.709 observaciones clínicas autorreportadas
  • 22 variables de entrada (hábitos de vida, condiciones médicas, datos demográficos)
  • Variable objetivo: DIABETE3 — riesgo de diabetes (binaria: 1=sí, 3=no en codificación original CDC)
  • Dataset procesado disponible en: Jesusrodriguezf90/brfss2015-diabetes-detection

Autor

Jesús Rodríguez Fernández — Data Scientist
🔗 LinkedIn · GitHub · HF Profile


Licencia

Uso no comercial. Dataset BRFSS 2015 de dominio público (CDC). Ver términos de uso del CDC para redistribución de datos derivados.