Los árboles de decisión son modelos especialmente didácticos porque toman decisiones mediante preguntas sucesivas. Su forma de razonar se parece mucho a la de un diagrama de flujo.
Por ejemplo, un árbol podría preguntar:
Según las respuestas, el modelo va recorriendo ramas hasta llegar a una predicción final.
Un árbol de decisión divide el espacio de datos en zonas cada vez más específicas. En cada nodo busca una regla del tipo:
si esta variable es menor o mayor que cierto valor, separar por aquí.
El objetivo es lograr que, después de varias divisiones, los grupos resultantes sean lo más homogéneos posible.
En clasificación, eso significa que cada hoja termine conteniendo casos de una misma clase o de clases muy parecidas.
Los árboles de decisión tienen varias ventajas pedagógicas y prácticas:
Por eso suelen aparecer entre los primeros algoritmos que vale la pena aprender en profundidad.
Un árbol solo puede volverse demasiado sensible a pequeñas variaciones del dataset. Si cambia un poco la muestra de entrenamiento, el árbol puede cambiar bastante su estructura.
Además, si se lo deja crecer demasiado, tiende al sobreajuste: aprende muy bien los datos vistos, pero generaliza peor ante casos nuevos.
Random forest intenta resolver ese problema usando muchos árboles en lugar de uno solo.
La lógica es:
En clasificación, el bosque suele decidir por votación. Así, se reduce la dependencia de un único árbol y el modelo se vuelve más robusto.
Cuando combinamos muchos árboles:
Por eso random forest es, en la práctica, una de las herramientas más confiables para empezar a resolver problemas tabulares.
Vamos a trabajar con un problema de compra de clientes. Usaremos dos variables:
Entrenaremos un DecisionTreeClassifier y un RandomForestClassifier, compararemos su exactitud y luego haremos una predicción sobre un nuevo cliente.
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
clientes = pd.DataFrame({
"visitas": [1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
"ingresos": [200, 250, 300, 320, 400, 500, 650, 700, 820, 950, 1100, 1300],
"compra": [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
})
X = clientes[["visitas", "ingresos"]]
y = clientes["compra"]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=42, stratify=y
)
arbol = DecisionTreeClassifier(max_depth=3, random_state=42)
bosque = RandomForestClassifier(n_estimators=50, max_depth=3, random_state=42)
arbol.fit(X_train, y_train)
bosque.fit(X_train, y_train)
y_pred_arbol = arbol.predict(X_test)
y_pred_bosque = bosque.predict(X_test)
print("Exactitud del árbol:", accuracy_score(y_test, y_pred_arbol))
print("Exactitud del random forest:", accuracy_score(y_test, y_pred_bosque))
nuevo_cliente = pd.DataFrame({
"visitas": [7],
"ingresos": [780]
})
pred_arbol = arbol.predict(nuevo_cliente)[0]
pred_bosque = bosque.predict(nuevo_cliente)[0]
prob_bosque = bosque.predict_proba(nuevo_cliente)[0, 1]
print("Predicción del árbol:", pred_arbol)
print("Predicción del random forest:", pred_bosque)
print(f"Probabilidad de compra según random forest: {prob_bosque:.3f}")
Salida resumida esperada:
Exactitud del árbol: ...
Exactitud del random forest: ...
Predicción del árbol: ...
Predicción del random forest: ...
Probabilidad de compra según random forest: ...
El árbol de decisión intenta construir una secuencia de reglas para separar compradores y no compradores. El random forest hace algo similar, pero repite el proceso muchas veces con distintos árboles y luego combina sus resultados.
En muchos casos, el bosque logra una predicción más robusta porque no depende de una sola estructura de decisión.
DecisionTreeClassifier(max_depth=3): crea un árbol limitado en profundidad para evitar que crezca sin control.RandomForestClassifier(n_estimators=50, max_depth=3): crea un conjunto de 50 árboles con profundidad limitada.fit(...): entrena ambos modelos con el mismo conjunto de datos.predict(...): produce la clase predicha.predict_proba(...): devuelve probabilidades estimadas de cada clase.accuracy_score(...): permite comparar ambos enfoques sobre el conjunto de prueba.En el ejemplo usamos max_depth=3. Esto limita cuántos niveles puede tener el árbol.
Si no se controla ese crecimiento, el árbol puede memorizar detalles demasiado específicos del entrenamiento. Limitar la profundidad es una de las formas más comunes de reducir sobreajuste.
Árbol de decisión:
Random forest: