
Sesión 2 — El árbol de decisión: nuestro primer clasificador de verdad
Seguimos en el mismo cuaderno de la Sesión 1. Ya tenemos cargado el dataset Breast Cancer Wisconsin (569 pacientes, 30 mediciones celulares por caso), ya vimos cuántos diagnósticos hay de cada tipo, y ya separamos un conjunto de prueba con train_test_split(..., stratify=y) — la parte de datos que el modelo no verá durante el entrenamiento, y que usaremos solo al final para comprobar si ha aprendido algo de verdad. Si en la Sesión 1 pensamos en canicas verdes y rojas repartidas en dos bolsas manteniendo la misma proporción, hoy usamos esas dos bolsas por primera vez: una para enseñar, otra para examinar.
Hoy entrenamos el primer modelo real del taller: un árbol de decisión.
¿Qué es un árbol de decisión?
Piensa en el juego de las veinte preguntas, o en un médico que va descartando diagnósticos con preguntas de sí/no: “¿la medición X es mayor que este valor? Si sí, pregunta esto otro. Si no, pregunta lo de más allá.” Cada pregunta reduce el número de pacientes que quedan por clasificar, hasta llegar a una respuesta: benigno o maligno.
Un árbol de decisión es exactamente eso, pero con una diferencia importante: nadie ha escrito esas preguntas a mano. El algoritmo las aprende solo, mirando los 455 pacientes de entrenamiento, y decidiendo en cada paso qué medición y qué umbral separan mejor a los pacientes con diagnósticos distintos. Eso es “entrenar” el modelo.
El código
from sklearn.tree import DecisionTreeClassifier
arbol = DecisionTreeClassifier(random_state=42)
arbol.fit(X_train, y_train)
exactitud = arbol.score(X_test, y_test)
print(f"Exactitud del árbol en el conjunto de prueba: {exactitud:.2%}")
fit es donde el árbol aprende las preguntas, usando solo los datos de entrenamiento. score hace algo distinto: coge el conjunto de prueba (que el árbol no ha visto nunca) y calcula qué proporción de esos pacientes clasifica correctamente. A ese número lo llamamos exactitud (accuracy).
Guardaos bien esta palabra, porque en la Sesión 3 vamos a usar otra parecida, “precisión”, que no significa lo mismo — precisión será algo mucho más concreto, relacionado con un tipo de error muy específico. Por ahora, exactitud es solo esto: de cada 100 pacientes del examen final, ¿a cuántos acierta el árbol?
¿Por qué no escalamos las variables?
Si habéis mirado el dataset, os habréis fijado en que las 30 mediciones no están en la misma escala: cosas como mean radius rondan la decena, y cosas como mean area están en cientos. En algunos algoritmos hay que arreglar esa diferencia de escala antes de entrenar, porque el modelo combina las variables entre sí y una escala mucho mayor que otra la haría pesar más de la cuenta sin motivo real.
Un árbol de decisión no tiene ese problema. Cada pregunta que hace es del tipo “¿esta medición concreta es mayor que este número?” — una variable sola, comparada con un umbral. Si multiplicáis todos los valores de esa medición por 1000, el árbol encuentra el mismo umbral (multiplicado por 1000) y toma exactamente la misma decisión. Por eso hoy no escalamos nada: sería un paso de más, que no cambiaría el resultado ni una centésima.
Viendo el árbol que ha aprendido solo
Podemos dibujar el árbol y ver literalmente las preguntas que ha elegido:
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
plt.figure(figsize=(20, 10))
plot_tree(
arbol,
feature_names=cancer.feature_names,
class_names=cancer.target_names,
filled=True,
impurity=False,
fontsize=8,
)
plt.show()
(cancer es el objeto que devolvió load_breast_cancer() en la Sesión 1 — de ahí salen los nombres de las mediciones y de los diagnósticos.)

Como no le hemos puesto ningún límite al árbol, sale bastante grande y denso — cuantas más preguntas hace, más se ajusta a estos 455 pacientes concretos. Es una imagen honesta de lo que ha aprendido, aunque cueste leerla entera de un vistazo.
Para verlo con más calma, dibujamos también solo las primeras preguntas. No hace falta recortar la imagen a mano: plot_tree tiene su propio parámetro max_depth, que decide cuántos niveles dibuja sin tocar para nada el árbol ya entrenado (el mismo con el que hemos calculado la exactitud):
plt.figure(figsize=(16, 8))
plot_tree(
arbol,
max_depth=2, # solo dibuja la raíz y dos niveles más
feature_names=cancer.feature_names,
class_names=cancer.target_names,
filled=True,
impurity=False,
fontsize=10,
)
plt.show()

[IMAGEN: primeras preguntas del árbol, obtenida con max_depth=2]
En la imagen se ve la raíz del árbol arriba del todo: la primera pregunta que ha elegido el algoritmo, de las 30 mediciones posibles, es sobre worst radius (el radio más grande medido en los núcleos celulares de la muestra): ¿es menor o igual que 16.795? De los 455 pacientes de entrenamiento, si la respuesta es “sí” (rama de la izquierda), la inmensa mayoría son benignos; si es “no” (rama de la derecha), la inmensa mayoría son malignos. Con una sola pregunta, el árbol ya separa bastante bien a los dos grupos.
Cada caja muestra samples (cuántos pacientes de entrenamiento han llegado hasta ahí) y value (cuántos de esos son malignos y cuántos benignos); class es el diagnóstico que da el árbol si se quedara solo con esa pregunta. La segunda fila es la siguiente ronda de preguntas, cada una afinando un poco más el diagnóstico dentro de su rama. Las cajas grises con puntos suspensivos son donde hemos cortado el dibujo a propósito: el árbol real sigue preguntando por debajo, hasta las muchas preguntas más que se ven en la imagen completa de arriba.
Qué viene después
En la Sesión 3 vamos a abrir la caja de los aciertos y los fallos: no todos los errores pesan igual cuando hablamos de un diagnóstico médico.
Slug: sesion-2-arbol-decision-cutler Extracto: En la Sesión 2 del taller CUTLER, el alumnado entrena su primer clasificador real — un árbol de decisión con scikit-learn — sobre datos médicos reales, sin escalar variables y midiendo su exactitud. Palabras clave: aidarac, montesteam, cutler, árbol de decisión, scikit-learn, ciencia de datos, aprendizaje automático, breast cancer wisconsin




