
Proyecto Taussig — Sesión 1: por qué este proyecto, de dónde vienen los datos, y la mujer que aprendió a escuchar el corazón con los dedos
Empezamos un proyecto nuevo, distinto de Javierre, Asadi y Fei-Fei. Esta vez el motivo no es un dataset bonito ni una técnica pendiente de estrenar: es una pregunta muy concreta, que no tiene nada de hipotética.
Un motivo real, no un ejercicio de clase
El 25 de agosto de 2007, el futbolista del Sevilla FC Antonio Puerta sufrió una parada cardiaca en pleno partido, en el Sánchez-Pizjuán. Murió tres días después, con solo 22 años. La causa fue una arritmia ventricular provocada por una displasia arritmogénica del ventrículo derecho, la causa más frecuente de muerte súbita en menores de 30 años. Puerta ya había sufrido al menos dos desmayos antes en su carrera, que nadie llegó a relacionar a tiempo con el corazón.
El 4 de marzo de 1990, Hank Gathers, estrella del baloncesto universitario estadounidense en Loyola Marymount, se desplomó en pleno partido tras un mate. No pudieron reanimarlo. Tenía 23 años. La autopsia reveló una miocardiopatía hipertrófica, y no era la primera señal: tres meses antes se había desmayado durante un tiro libre, le habían diagnosticado una arritmia, y aun así los médicos le habían dado permiso para seguir jugando.
Y luego está Christian Eriksen. En junio de 2021 sufrió un paro cardiaco en pleno partido de la Eurocopa, y lo reanimaron sobre el césped. Le implantaron un desfibrilador automático. En junio de 2026 volvió a colapsar — y esta vez nadie tuvo que correr a reanimarlo, porque el propio aparato detectó la arritmia y actuó solo, sin que nadie interviniera desde fuera.
Tres historias, una sola pregunta: ¿y si hubiera existido antes una forma de leer esa señal a tiempo? No es ciencia ficción — es literalmente lo que le pasó a Eriksen la segunda vez. Eso es lo que vamos a explorar en este proyecto: si un modelo entrenado con miles de latidos reales es capaz de distinguir un corazón que late bien de uno que no.
Por qué se llama Proyecto Taussig
Le ponemos nombre a este proyecto en honor a Helen Brooke Taussig (1898-1986), la médica que fundó la cardiología pediátrica como campo propio de la medicina.
Taussig se quedó parcialmente sorda de niña, por una infección de oído, y ya de adulta perdió el oído por completo. Para seguir ejerciendo, aprendió a leer los labios de sus pacientes y a usar audífonos — pero además, y esto es lo más extraordinario, desarrolló su propio método para diagnosticar el corazón sin necesidad de oírlo: en vez de un estetoscopio, usaba los dedos, apoyándolos sobre el pecho de sus pacientes para sentir el ritmo de sus latidos. Diagnosticaba problemas cardiacos por el tacto, no por el sonido. Donde le faltaba un sentido, se inventó otra forma de percibir exactamente la misma información.
Con esa forma de “escuchar” con las manos, Taussig identificó un patrón que nadie había atado antes: los bebés que nacían con el corazón malformado y “morados” (la conocida como síndrome del bebé azul, causada sobre todo por la tetralogía de Fallot) mejoraban de forma extraña cuando, además, tenían otro defecto congénito que en teoría también era malo. Esa intuición, discutida al principio con escepticismo por sus colegas cirujanos, se convirtió en 1944 en una operación real —hoy conocida como el shunt de Blalock-Thomas-Taussig— que transformaba a bebés que se ahogaban al beber leche en niños capaces de jugar con normalidad. Cuando Taussig murió, decenas de miles de vidas infantiles se habían salvado gracias a esa idea. En 1965 se convirtió en la primera mujer, y la primera pediatra, en presidir la American Heart Association.
Hay algo que conecta directamente su historia con la nuestra: Taussig encontró, en un sentido que le faltaba, una vía distinta para detectar algo que a simple oído era invisible. Eso es exactamente lo que le vamos a pedir a un modelo de aprendizaje automático: que “sienta” en una señal eléctrica del corazón un patrón que, a nuestros ojos y oídos, no salta a la vista.
De dónde vienen los datos
Vamos a trabajar con electrocardiogramas (ECG) reales, no simulados. Un ECG registra la actividad eléctrica del corazón a lo largo del tiempo: cada latido dibuja una forma característica, y esa forma cambia cuando el ritmo del corazón falla.
El conjunto de datos que usaremos es el “ECG Heartbeat Categorization Dataset”, publicado por Mohammad Kachuee, Shayan Fazeli y Majid Sarrafzadeh en su artículo “ECG Heartbeat Classification: A Deep Transferable Representation” (2018). Detrás de él está una de las bases de datos más usadas en toda la historia del análisis automático del corazón: la MIT-BIH Arrhythmia Database, publicada por PhysioNet, con registros reales de ECG de pacientes de verdad, recogidos por el Beth Israel Hospital de Boston.
Los autores del dataset ya hicieron un trabajo que a nosotros nos interesa mucho: recortaron la señal continua de cada paciente en latidos individuales, y ajustaron cada uno a exactamente 188 números (rellenando con ceros los latidos más cortos). El resultado son 109.446 latidos reales, cada uno guardado como una fila de un archivo CSV — así que, aunque el contenido es nuevo (una señal eléctrica en vez de genes o imágenes), la forma de cargarlo es la misma que ya conocéis de Javierre: un pd.read_csv() y ya está. Nada de instalar TensorFlow todavía.
Qué significa cada columna, y cada clase
Cada fila tiene 189 columnas:
- Las primeras 188 son los valores numéricos que dibujan la forma del latido — piensa en ellas como una fotografía, tomada 188 veces por segundo, de cómo se movía la señal eléctrica del corazón durante ese latido.
- La última columna es la clase: qué tipo de latido es, según lo etiquetó personal médico especializado revisando cada uno. Hay cinco:
| Código | Significado |
|---|---|
| N | Normal — un latido sano |
| S | Arritmia supraventricular — el fallo empieza por encima de los ventrículos |
| V | Arritmia ventricular — el fallo está en los ventrículos, la parte que bombea la sangre al resto del cuerpo |
| F | Latido de fusión — una mezcla entre un latido normal y uno anómalo |
| Q | Latido no clasificable con las reglas habituales |
La categoría V, la ventricular, es precisamente el tipo de arritmia asociado a la muerte súbita cardiaca — el mismo mecanismo que estuvo detrás de lo que le pasó a Antonio Puerta y a Hank Gathers. No estamos diciendo que este dataset contenga sus latidos (no los contiene: son pacientes anónimos de un hospital de Boston), sino que la categoría que vamos a aprender a reconocer es, biológicamente, el mismo tipo de fallo.
Cómo preparar todo antes de la próxima sesión
- Entra en
kaggle.com/datasets/shayanfazeli/heartbeatcon tu cuenta de Kaggle y descarga el dataset. - Descomprime el contenido en una carpeta de este proyecto. Nos interesan, de momento, dos archivos:
mitbih_train.csvymitbih_test.csv. - Guarda esos dos archivos en la misma carpeta donde tengas el cuaderno de Jupyter de esta sesión, igual que hicisteis con
leucemia_4genes.csven Javierre.
No hace falta instalar nada nuevo: pandas y matplotlib, que ya conocéis desde CUTLER, son suficientes para esta primera sesión.
Primer vistazo a los datos
Este dataset no trae nombres de columna en la cabecera del CSV, así que se lo decimos a pandas con header=None:
import pandas as pd
entrenamiento = pd.read_csv("mitbih_train.csv", header=None)
entrenamiento.shape
# La última columna (la 187, contando desde 0) es la clase
entrenamiento[187].value_counts()
Vais a ver que las clases están lejos de repartidas por igual — la inmensa mayoría de latidos son normales, y eso es una buena noticia para cualquier corazón, pero un reto para un modelo, algo que ya sabemos manejar desde Asadi.
Y ahora, lo más parecido a lo que hacía Taussig con los dedos, pero con una gráfica en vez de con el tacto — dibujamos la forma real de un latido normal y de uno ventricular, uno junto al otro:
import matplotlib.pyplot as plt
# Cogemos el primer latido normal (clase 0) y el primer latido ventricular (clase 2)
latido_normal = entrenamiento[entrenamiento[187] == 0].iloc[0, :187]
latido_ventricular = entrenamiento[entrenamiento[187] == 2].iloc[0, :187]
fig, ejes = plt.subplots(1, 2, figsize=(10, 4))
ejes[0].plot(latido_normal)
ejes[0].set_title("Latido normal (N)")
ejes[1].plot(latido_ventricular)
ejes[1].set_title("Arritmia ventricular (V)")
plt.tight_layout()
plt.show()
[COMPLETAR EN CLASE: ¿se nota a simple vista la diferencia entre las dos formas, o hay que fijarse mucho?]

Próximo paso
En la próxima sesión entrenaremos nuestro primer modelo real sobre estos latidos — con las mismas herramientas de siempre, DecisionTreeClassifier y RandomForestClassifier, tratando los 188 números de cada latido exactamente igual que tratamos los 4 genes de Javierre. La diferencia es que esta vez el modelo tendrá que elegir entre cinco categorías, no dos — la primera vez en toda la familia de proyectos que pedimos una clasificación de más de dos clases sobre datos en tabla.



