Árboles de Decisión: de la intuición a la predicción

Jorge SaavedraJorge Saavedra
·28 de abril, 2025·10 min de lectura
machine-learningiapythonalgoritmosarboles-de-decision
Imagina que llegas a un restaurante y tienes que decidir qué pedir. Sin darte cuenta, tu cerebro está ejecutando un árbol de decisión: ¿tienes hambre? Sí. ¿Quieres algo ligero o pesado? Ligero. ¿Hay ensaladas en el menú? Sí. Listo, ensalada. Cada pregunta te lleva a una rama diferente, y al final del camino está tu decisión.
Los árboles de decisión en machine learning funcionan exactamente igual: una serie de preguntas encadenadas que, dependiendo de las respuestas, conducen a una clasificación o predicción. Lo fascinante es que la máquina aprende sola cuáles son las mejores preguntas y en qué orden hacerlas. Este artículo te guiará desde el concepto básico hasta la matemática detrás, con implementación en Python y visualización incluida.

¿Qué es un árbol de decisión?

Un árbol de decisión es un modelo predictivo que toma decisiones dividiendo un conjunto de datos en subconjuntos cada vez más homogéneos. Cada nodo del árbol representa una pregunta sobre un atributo, y cada rama una posible respuesta. Las hojas finales contienen la decisión o clasificación resultante.
Ejemplo intuitivo: Imagina que quieres saber si deberías salir a jugar al aire libre. Las preguntas podrían ser:
  • ¿Está soleado?
    • Sí: ¿La humedad es alta?
      • Sí: No jugar
      • No: Sí jugar
    • No: ¿Está lloviendo?
      • Sí: ¿Hay viento fuerte?
        • Sí: No jugar
        • No: Sí jugar
      • No: Sí jugar
Pero ¿cómo sabe la máquina cuál pregunta hacer primero? ¿Por qué empezar por "¿Está soleado?" y no por "¿Hay viento?"? La respuesta está en dos conceptos matemáticos: la entropía y la ganancia de información.

Entropía: midiendo el desorden

La entropía es una medida de incertidumbre o desorden en un conjunto de datos. Si todos los elementos pertenecen a la misma clase, la entropía es 0 (certeza total). Si están repartidos exactamente por la mitad, la entropía es 1 (máxima incertidumbre).
La fórmula es:
H(S) = - ∑( p_i * log2(p_i) )
Donde p_i es la proporción de elementos de la clase i en el conjunto S.

Calculemos con nuestro dataset

Nuestro dataset tiene 14 muestras: 9 "sí" y 5 "no".

  • p(sí) = 9/14 = 0.643
  • p(no) = 5/14 = 0.357
  • H(S) = -(0.643 * log2(0.643) + 0.357 * log2(0.357))
  • H(S) = -(0.643 * (-0.637) + 0.357 * (-1.486))
  • H(S) = -(-0.410 + (-0.531))
  • H(S) = 0.94

Un valor de 0.94 nos dice que el dataset tiene alta incertidumbre: no podemos predecir fácilmente la clase sin más información.

Information Gain: eligiendo la mejor pregunta

El árbol de decisión necesita elegir, en cada nodo, el atributo que mejor separa los datos. Para eso calcula la ganancia de información (information gain) de cada atributo: cuánto se reduce la entropía al dividir por ese atributo.
IG(S, A) = H(S) - ∑( |Sv| / |S| * H(Sv) )
Donde Sv es el subconjunto de S donde el atributo A tiene el valor v.

Calculemos el Information Gain para 'Ambiente'

Dividimos el dataset por "Ambiente":

  • Soleado (5 muestras): 2 sí, 3 no → H = 0.97
  • Nublado (4 muestras): 4 sí, 0 no → H = 0.0
  • Lluvioso (5 muestras): 3 sí, 2 no → H = 0.97

Entropía ponderada:

(5/14 * 0.97) + (4/14 * 0.0) + (5/14 * 0.97) = 0.347 + 0 + 0.347 = 0.694

IG(Ambiente) = 0.94 - 0.694 = 0.246

El árbol repite este cálculo para cada atributo y elige el que tenga el mayor information gain. En este caso, "Ambiente" gana.

Construyendo un árbol en Python

Usaremos un dataset pequeño con condiciones climáticas y la decisión de jugar o no.
#AmbienteTemperaturaHumedadVientoClase
1soleadoaltaaltafalsono
2soleadoaltaaltaverdaderono
3nubladoaltaaltafalso
4lluviosomediaaltafalso
5lluviosobajanormalfalso
6lluviosobajanormalverdaderono
7nubladobajanormalverdadero
8soleadomediaaltafalsono
9soleadobajanormalfalso
10lluviosomedianormalfalso
11soleadomedianormalverdaderono
12nubladomediaaltaverdadero
13nubladoaltanormalfalso
14lluviosomediaaltaverdaderono
Vamos a darle forma y escribirlo de manera que podamos insertarlo en un dataset. También puedes usar pandas para importarlo como CSV; sin embargo, aquí lo haremos de forma manual.
python
import pandas as pd

data = {
    'Ambiente': ['soleado', 'soleado', 'nublado', 'lluvioso', 'lluvioso', 'lluvioso', 'nublado', 'soleado', 'soleado', 'lluvioso', 'soleado', 'nublado', 'nublado', 'lluvioso'],
    'Temperatura': ['alta', 'alta', 'alta', 'media', 'baja', 'baja', 'baja', 'media', 'baja', 'media', 'media', 'media', 'alta', 'media'],
    'Humedad': ['alta', 'alta', 'alta', 'alta', 'normal', 'normal', 'normal', 'alta', 'normal', 'normal', 'normal', 'alta', 'normal', 'alta'],
    'Viento': ['falso', 'verdadero', 'falso', 'falso', 'falso', 'verdadero', 'verdadero', 'falso', 'falso', 'falso', 'verdadero', 'verdadero', 'falso', 'verdadero'],
    'Clase': ['no', 'no', 'si', 'si', 'si', 'no', 'si', 'no', 'si', 'si', 'no', 'si', 'si', 'no']
}

df = pd.DataFrame(data)
python
from sklearn.preprocessing import LabelEncoder

le = LabelEncoder()
for column in df.columns:
    df[column] = le.fit_transform(df[column])
python
from sklearn.tree import DecisionTreeClassifier

X = df.drop('Clase', axis=1)
y = df['Clase']

modelo = DecisionTreeClassifier(criterion='entropy')
modelo.fit(X, y)
python
from sklearn import tree
import matplotlib.pyplot as plt

plt.figure(figsize=(12,8))
tree.plot_tree(modelo, feature_names=X.columns, class_names=['no', 'si'], filled=True)
plt.show()

Prueba el árbol de decisión

Ahora que entiendes cómo funciona, pruébalo tú mismo. Selecciona las condiciones climáticas y observa cómo el árbol recorre sus nodos hasta llegar a una predicción:

Selecciona las condiciones climáticas y observa cómo el árbol toma su decisión paso a paso:

1
¿El ambiente es lluvioso o nublado?
Ambiente = soleadosoleado es soleado, seguimos por la rama derecha.
2
¿La humedad es normal?
Humedad = altaHumedad alta: necesitamos ver la temperatura.
3
¿La temperatura es alta?
Temperatura = altaTemperatura alta con humedad alta y sol: no se juega.
Predicción del modelo:
No jugar
3 decisiones tomadas para llegar a esta predicción

Análisis del árbol generado

Al observar el árbol de decisión entrenado, notamos que:

  • La raíz del árbol es el atributo Ambiente. Esto confirma nuestro cálculo: Ambiente tiene el mayor information gain (0.246), por lo que es la variable que mejor separa los datos.
  • Si Ambiente <= 1.5, el siguiente atributo evaluado es Viento. Cuando no hay viento (Viento <= 0.5), se predice jugar con certeza (entropía 0.0 en 5 muestras).
  • Si hay viento, se vuelve a considerar el Ambiente, donde la decisión ya no es tan clara (entropía 1.0 con 2 y 2 muestras).
  • Si Ambiente > 1.5, se analiza Humedad, y si esta no es baja, se consulta la Temperatura para resolver la clasificación.

En resumen, el modelo revela que Ambiente es la variable más influyente, mientras queViento y Humedad refinan las decisiones. La Temperatura aparece solo cuando las condiciones anteriores no son suficientes para una clasificación clara. Este tipo de interpretabilidad es una de las mayores ventajas de los árboles de decisión.

Overfitting y poda

Un árbol de decisión puede crecer hasta tener una hoja por cada muestra del dataset. Cuando eso pasa, el árbol memoriza los datos de entrenamiento en lugar de aprender patrones generales. A esto se le llama overfitting (sobreajuste): el modelo funciona perfecto con datos que ya vio, pero falla con datos nuevos.
La solución es la poda: limitar el crecimiento del árbol para que generalice mejor. En sklearn, los parámetros más comunes son:
  • max_depth: profundidad máxima del árbol
  • min_samples_leaf: mínimo de muestras que debe tener una hoja
  • min_samples_split: mínimo de muestras para dividir un nodo
python
# Árbol con poda
modelo_podado = DecisionTreeClassifier(
    criterion='entropy',
    max_depth=3,
    min_samples_leaf=2
)
modelo_podado.fit(X, y)

# Visualizar
plt.figure(figsize=(10, 6))
tree.plot_tree(modelo_podado, feature_names=X.columns, class_names=['no', 'si'], filled=True)
plt.title('Árbol de decisión con poda')
plt.show()

¿Cuándo podar?

No existe un valor universal para estos parámetros. Lo ideal es usar validación cruzada (cross-validation) para encontrar la combinación que mejor generaliza a datos nuevos. En la práctica, un buen punto de partida es limitar la profundidad a 3-5 niveles y requerir al menos 5 muestras por hoja.

De un árbol a un bosque: intro a Random Forest

Si un solo árbol puede tener problemas de overfitting, ¿qué pasa si entrenamos muchos árboles y los hacemos votar? Esa es exactamente la idea detrás de Random Forest.
El algoritmo entrena múltiples árboles de decisión, cada uno con:
  • Un subconjunto aleatorio de las muestras del dataset (con reemplazo)
  • Un subconjunto aleatorio de los atributos en cada división
Al momento de predecir, cada árbol emite su voto y la clase con más votos gana. Esta diversidad entre árboles reduce el overfitting porque los errores individuales tienden a cancelarse entre sí.

Conclusión

En este artículo recorrimos el camino completo de los árboles de decisión: desde la intuición de "una serie de preguntas" hasta la matemática que los hace funcionar (entropía e information gain), pasando por su implementación en Python y sus limitaciones (overfitting).
Los árboles de decisión son herramientas poderosas por su interpretabilidad. Puedes mirar un árbol entrenado y entender exactamente por qué tomó cada decisión, algo que no es posible con modelos más complejos como redes neuronales.
En el siguiente artículo exploraremos Random Forest en profundidad: cómo implementarlo, cuándo usarlo, y por qué se ha convertido en uno de los algoritmos más populares en machine learning.

Posts que podrian interesarte