
Proyecto Taussig — Sesión 2: el primer modelo, y la primera vez que pedimos más de dos respuestas
En la sesión anterior conocimos el dataset: 109.446 latidos reales, cada uno reducido a 188 números, sacados de la MIT-BIH Arrhythmia Database. También conocimos a Helen Taussig, la cardióloga que aprendió a “escuchar” el corazón con los dedos cuando se quedó sorda. Hoy le pedimos a un modelo que haga algo parecido: que sienta, en esos 188 números, un patrón que a nosotros no nos dice nada a simple vista.
Una diferencia importante con todo lo anterior: los datos ya vienen repartidos
Hasta ahora, en CUTLER y en Javierre, el primer paso siempre era el mismo: cargar un único archivo y repartirlo nosotros mismos entre entrenamiento y prueba con train_test_split(), cuidando de usar stratify para que las canicas de cada color quedaran bien mezcladas en las dos bolsas.
Aquí no hace falta. Quien publicó el dataset ya hizo ese reparto por nosotros: por eso descargasteis dos archivos, no uno. mitbih_train.csv es la bolsa de entrenamiento, mitbih_test.csv es la bolsa de prueba, y ya están repartidas de fábrica. Así que hoy nos saltamos un paso que en Javierre iba entre cargar los datos y entrenar el modelo:
import pandas as pd
entrenamiento = pd.read_csv("mitbih_train.csv", header=None)
prueba = pd.read_csv("mitbih_test.csv", header=None)
entrenamiento.shape, prueba.shape
Y separamos, en cada uno, las columnas que describen el latido (0 a 186) de la columna que dice qué tipo de latido es (la 187):
X_entrenamiento = entrenamiento.iloc[:, :187]
y_entrenamiento = entrenamiento[187]
X_prueba = prueba.iloc[:, :187]
y_prueba = prueba[187]
Nada de train_test_split, nada de stratify. Ese trabajo ya está hecho — hoy simplemente lo aprovechamos.
El modelo: el mismo árbol de siempre
Para entrenar usamos exactamente la misma herramienta que en CUTLER y en Javierre: DecisionTreeClassifier. Y por la misma razón de siempre, tampoco hace falta escalar los 188 valores del latido antes de entrenar — ya lo vimos en CUTLER: un árbol de decisión no mide distancias entre puntos, solo va comparando un valor con un umbral en cada rama, así que le da igual que unas columnas tengan números más grandes que otras.
from sklearn.tree import DecisionTreeClassifier
arbol = DecisionTreeClassifier(random_state=42)
arbol.fit(X_entrenamiento, y_entrenamiento)
arbol.score(X_prueba, y_prueba)
[COMPLETAR CON VUESTROS DATOS REALES: exactitud del árbol = ___]

Lo nuevo de hoy: por primera vez, el modelo tiene que elegir entre más de dos opciones
En CUTLER el árbol elegía entre benigno y maligno. En Javierre, entre ALL y AML. Siempre dos opciones. Hoy, por primera vez en toda la familia de proyectos, le pedimos al árbol que elija entre cinco: N, S, V, F o Q.
Merece la pena pararse un segundo en esto, porque cambia lo que significa acertar. Cuando solo hay dos clases, equivocarse quiere decir confundir una cosa con la otra — no hay más posibilidades. Con cinco clases, equivocarse puede querer decir cosas muy distintas: no es lo mismo que el árbol confunda un latido normal (N) con uno de fusión (F), que apenas se parecen y son difíciles de distinguir hasta para un cardiólogo, que confundirlo con uno ventricular (V) — el tipo de arritmia que nos trajo a este proyecto. La exactitud de hoy es un único número que mezcla todos esos errores por igual, así que no nos dice todavía con qué se confunde el modelo. A eso le dedicaremos la próxima sesión.
Por ahora, os proponemos mirar por encima el reparto de aciertos por clase con el método .value_counts() que ya conocéis, comparando cuántos latidos de cada clase hay realmente en y_prueba frente a cuántos predice el árbol:
predicciones = arbol.predict(X_prueba)
import pandas as pd
pd.Series(predicciones).value_counts()
[COMPLETAR EN CLASE: compara este reparto con y_prueba.value_counts() — ¿el árbol predice todas las clases, o hay alguna que casi nunca elige?]
Un aviso sobre este primer número
Como ya nos pasó en Javierre con solo 15 pacientes de prueba, conviene no sacar conclusiones demasiado rápido de un único número de exactitud — aunque aquí el motivo es justo el contrario. En Javierre el conjunto de prueba era tan pequeño que un solo paciente mal clasificado cambiaba mucho el resultado. Aquí el conjunto de prueba es enorme (más de 20.000 latidos), así que el número va a ser mucho más estable — pero eso no lo convierte automáticamente en una buena noticia: con clases tan desequilibradas como vimos en la sesión anterior (la inmensa mayoría de latidos son normales), un modelo perezoso podría conseguir una exactitud que parece alta simplemente acertando casi siempre con la clase mayoritaria, y fallando en las clases raras — que son, precisamente, las que más nos importan.
Próximo paso
En la próxima sesión vamos a abrir esa caja negra que es la exactitud: construiremos una matriz de confusión para las cinco clases, como hicimos en CUTLER y en Javierre, pero esta vez de 5×5 en vez de 2×2. Ahí veremos, con nombres y apellidos, con qué se confunde el árbol — y en concreto, si acierta o no con los latidos ventriculares (V), que es la clase que de verdad nos trajo hasta aquí.




