lección 7
Que el comité clínico pueda decidir con esto
Montar las figuras y la tabla de decisión en lenguaje de pacientes, escribir el README, y defender el punto de equilibrio con la curva de coste.
⏱ 55 min
## Viernes, 10:00. Dos horas para el comité
A las doce presentas ante Beatriz y Tomás, y lo que lleves tiene que poder entenderse sin una sola palabra de jerga. Beatriz no quiere oír «recall 0,90»: quiere oír «de cada 100 lesiones graves, el sistema pesca 90 y se le escapan 10, frente a las 58 que se escapaban con el ajuste de fábrica». Tomás no quiere oír «795 falsos positivos»: quiere oír «generas unas 500 consultas de más al mes, y aquí tienes el margen que tengo para absorberlas». Tu trabajo del viernes es traducir toda la semana a ese lenguaje, con tres figuras que hablen solas y una tabla de decisión que cualquiera pueda leer.
Las tres figuras son las que has ido construyendo: la curva de coste frente al umbral con el mínimo marcado, que enseña por qué 0,12 y no 0,5; la curva de calibración antes y después, que enseña por qué las probabilidades ahora son de fiar; y la tabla de decisión en lenguaje de pacientes, que pone cara a cada número. Y al lado de cada regla, una referencia: lo que costaría derivar a todas. La regla manual del fundador nunca se midió; en el informe lo dices así, y propones medirla con los mismos datos antes de compararla.
## La ratio no es tuya: tres filas para el comité
Toda la semana has usado 20:1. Esa cifra no sale de los datos ni la elige el científico de datos: cuánto vale un grave perdido frente a una consulta de más es una decisión clínica, y la firma el comité de Beatriz. Lo que sí te toca es enseñarle qué cambia si mueve la ratio. Así que llevas tres filas: 10:1, 20:1 y 40:1. Para cada una, el umbral se elige en validación y se mide en la prueba. La cuenta teórica te dice hacia dónde se moverá: 1/11 ≈ 0,09 con 10:1, 1/21 ≈ 0,05 con 20:1 y 1/41 ≈ 0,02 con 40:1.
Lo que vas a ver es incómodo y útil. Con 10:1 el modelo ahorra frente a derivar a todas (1110 frente a 1256 en la prueba). Con 20:1 queda cerca de esa regla trivial, incluso algo por encima en la prueba. Con 40:1 el umbral baja a 0,03 y la regla es, en la práctica, derivar a todas. Es decir: cuanto más cara pone el comité la vida de un grave perdido, menos sitio queda para el modelo y más consultas tiene que absorber Tomás. Esa conversación es la que el comité necesita tener, y tu tabla es la que la hace posible.
## ¿Funciona igual para todos? Una tabla por grupo
Antes de llevar una regla de triaje a una clínica hay una pregunta que el comité te va a hacer, y con razón: ¿se le escapan más graves a algún grupo de pacientes? Una regla que va bien de media puede ir peor con las mujeres, o con los mayores. Los datos traen sexo y edad, así que puedes mirarlo: en la prueba, con el bosque y el umbral 0,12, cuentas por grupo los graves, los que se escapan y las consultas de más.
1prueba = X_te.copy()2prueba['grave'] = y_te3prueba['urgente'] = (rf.predict_proba(X_te)[:, 1] >= 0.12).astype(int)4prueba['sexo'] = np.where(prueba['sexo_F'] == 1, 'F', 'M')5prueba['edad_grupo'] = pd.cut(prueba['edad'], [0, 40, 60, 120], right=False,6 labels=['<40', '40-59', '60+'])7for col in ['sexo', 'edad_grupo']:8 for grupo, g in prueba.groupby(col, observed=True):9 graves = int(g['grave'].sum())10 pescados = int(((g['urgente'] == 1) & (g['grave'] == 1)).sum())11 de_mas = int(((g['urgente'] == 1) & (g['grave'] == 0)).sum())12 print(f"{col}={grupo}: lesiones={len(g)} graves={graves} "13 f"escapados={graves - pescados} recall={pescados / graves:.2f} "14 f"consultas_de_mas={de_mas}")1516# sexo=F: lesiones=660 graves=133 escapados=14 recall=0.89 consultas_de_mas=32917# sexo=M: lesiones=912 graves=183 escapados=18 recall=0.90 consultas_de_mas=46618# edad_grupo=<40: lesiones=472 graves=56 escapados=6 recall=0.89 consultas_de_mas=19319# edad_grupo=40-59: lesiones=733 graves=161 escapados=19 recall=0.88 consultas_de_mas=36020# edad_grupo=60+: lesiones=367 graves=99 escapados=7 recall=0.93 consultas_de_mas=242
Rendimiento por grupo en la prueba (bosque, umbral 0,12, corte por paciente). Va a continuación del código de la tabla de decisión, con el mismo rf y la misma prueba.
En estos datos no se ve una diferencia clara: el recall va de 0,88 a 0,93 en todos los grupos. Pero léelo con prudencia. Los grupos son pequeños (56 graves en los menores de 40), así que un par de graves arriba o abajo mueve mucho la cifra. Y falta el grupo que más importa en dermatología: el tipo de piel (fototipo). Los datos no lo traen, y los modelos de piel se suelen entrenar con pocas pieles oscuras. Sin esa columna no puedes saber si la regla falla más con ellas, y el informe tiene que decirlo como límite.
## El README: el proyecto se convierte en portfolio
A lo largo de la semana has ido montando, pieza a pieza, un repositorio completo: cinco scripts numerados en src/, las consultas en sql/, los datos en datos/, y el requirements.txt con las dependencias. Lo único que falta es el README, y lo escribes tú. No es un trámite: es la pieza que explica qué hace el proyecto, cómo se ejecuta, y —lo más importante— cuál fue el hallazgo. Es lo que un reclutador o un compañero leen primero, y lo que demuestra que entiendes la diferencia entre un modelo con buen número y una decisión que se puede firmar.
1cribado-dermia/2├── README.md ← lo escribes HOY (el hallazgo del caso)3├── requirements.txt ← pandas, numpy, scikit-learn, matplotlib, duckdb4├── datos/ ← lesiones.csv, desenlaces.csv, tabla_modelado.csv5├── sql/ ← 01_desbalanceo.sql, 02_calibracion_color.sql6└── src/7 ├── 01_explorar.py ← carga, prevalencia, encuadre de costes8 ├── 02_features.py ← limpieza y tabla de modelado9 ├── 03_modelar.py ← dos clasificadores, AUC, matriz a 0,510 ├── 04_decidir.py ← umbral por coste, calibración, remate11 └── 05_informe.py ← figuras y tabla de decisión
El repositorio completo que has montado sin darte cuenta, un ejercicio cada vez. Al juntar las soluciones en orden, cada script de src/ se ejecuta de principio a fin fuera del navegador. Es tu pieza de portfolio: un proyecto de cribado con decisión por coste, de verdad.
Consejo de senior: en el README, el hallazgo va antes que el método. No empieces por «entrené una logística y un bosque»; empieza por «el ajuste de fábrica dejaba escapar a más de la mitad de los graves, y el umbral por coste lo arregla». Quien lee un README quiere saber qué descubriste, no qué botones pulsaste. El cómo viene después, para quien quiera reproducirlo.
## comentarios
Reporta erratas, ayuda a otros o comparte tu opinión. Sé constructivo.
Inicia sesión para comentar y responder.
cargando comentarios...
Regístrate para guardar tu progreso.