
Proyecto Javierre — Sesión 4: Random Forest, el comité de árboles
En la Sesión 2 entrenamos un único árbol de decisión. Un solo árbol tiene un punto débil: es muy sensible a los datos con los que ha aprendido — con solo 57 pacientes de entrenamiento, cambiar un par de ellos podría cambiar sus preguntas por completo. Hoy damos el salto al algoritmo que ya conocemos de CUTLER: Random Forest, creado por Adele Cutler y Leo Breiman.
Recordando la idea: un comité, no un solo médico
Un Random Forest entrena muchos árboles de decisión independientes — cada uno con un subconjunto aleatorio de pacientes y de genes distintos en cada pregunta — y los deja votar. Si 85 de 100 árboles dicen “ALL”, la decisión final del bosque es ALL.
Entrenando el bosque en scikit-learn
from sklearn.ensemble import RandomForestClassifier
# 1. Crear el bosque con 100 árboles de decisión
bosque = RandomForestClassifier(n_estimators=100, random_state=42)
# 2. Entrenar a todos los árboles a la vez
bosque.fit(X_train, y_train)
# 3. Evaluar la exactitud en el conjunto de prueba
exactitud_bosque = bosque.score(X_test, y_test)
print(f"Exactitud del Random Forest en el conjunto de prueba: {exactitud_bosque:.2%}")
[COMPLETAR CON VUESTROS DATOS REALES: exactitud del árbol de la Sesión 2 = ___ | exactitud del Random Forest = ___]

Comparando el árbol con el bosque
from sklearn.metrics import classification_report
y_pred_bosque = bosque.predict(X_test)
print("--- INFORME DEL RANDOM FOREST ---")
print(classification_report(y_test, y_pred_bosque))

Comparad la exhaustividad de ALL y de AML con las que obtuvisteis en la Sesión 3 con el árbol único: ¿sube alguna, baja, o se queda igual? No hay una respuesta garantizada de antemano — por eso lo comprobamos con los datos.
[COMPLETAR CON VUESTROS DATOS REALES: exhaustividad de ALL con el árbol = ___ | con el bosque = ___. Exhaustividad de AML con el árbol = ___ | con el bosque = ___]
¿Qué gen pesa más en la decisión?
Aquí es donde este proyecto tiene algo que CUTLER no podía enseñar: solo tenemos 4 genes, elegidos a mano en la Sesión 1 por su significado clínico real (MPO y CD33 como marcadores mieloides, CD19 y TdT como marcadores linfoides). Con feature_importances_ podemos comprobar si el bosque, entrenado sin saber nada de biología, ha aprendido a apoyarse en esos mismos genes.
import pandas as pd
import matplotlib.pyplot as plt
# Crear una serie con la importancia de cada gen
importancias = pd.Series(bosque.feature_importances_, index=X.columns)
importancias = importancias.sort_values(ascending=False)
# Dibujar la importancia de los 4 genes
plt.figure(figsize=(8, 4))
importancias.plot(kind='barh', color='skyblue')
plt.title("Importancia de cada gen según el Random Forest")
plt.xlabel("Importancia relativa")
plt.gca().invert_yaxis() # Poner el más importante arriba
plt.show()
Las importancias de los 4 genes suman entre todas el 100%, así que una barra grande significa que ese gen concentra buena parte del peso en las decisiones del bosque.
[COMPLETAR CON VUESTROS DATOS REALES: gen más importante según el bosque = ___. ¿Es un marcador mieloide o linfoide? ¿Coincide con lo que esperaríais después de la Sesión 1?]

Qué viene después
Hemos construido un modelo más robusto que un solo árbol. Pero toda esta comparación se ha apoyado en una única partición de entrenamiento y prueba, la misma desde la Sesión 2 — y con solo 15 pacientes de examen, esa partición concreta pudo tocarnos por pura suerte. En la próxima sesión lo comprobaremos con validación cruzada, igual que cerramos el taller CUTLER.



