Árboles de decisión
machine learning, aprendizaje automatico, Python, algebra lineal, optimizacion, regresion lineal, clasificacion, estadistica
1 Intuición
Para explicar de forma intuitiva cómo funcionan, vamos a ver un ejemplo del sector financiero: la aprobación de préstamos bancarios.
Imagina que trabajas en el departamento de riesgos de un banco y, a partir de ciertas características del cliente, quieres entrenar un clasificador automatizado que te diga rápidamente si se debe aprobar un préstamo (\(Y = 1\)) o rechazarlo (\(Y = 0\)).
Para este propósito, se dispone de un conjunto de 10 ejemplos de entrenamiento. Cada ejemplo contiene tres características de entrada (\(X\)) y una etiqueta de verdad fundamental (\(Y\)):
- \(X_1\) (Historial crediticio): Bueno o Malo.
- \(X_2\) (Nivel de ingresos): Altos o Bajos.
- \(X_3\) (Empleo estable): Sí o No.
- \(Y\) (Etiqueta objetivo): Préstamo aprobado (1) o Préstamo rechazado (0).
El conjunto de entrenamiento contiene cinco solicitudes aprobadas y cinco rechazadas.
Las variables de entrada \(X\) son de naturaleza categórica; es decir, adoptan únicamente un conjunto reducido de valores discretos y cualitativos. Además, es una tarea de clasificación binaria, ya que la etiqueta objetivo \(Y\) solo puede tener los valores de \(1\) o \(0\). Por ahora, cada característica (\(X_1, X_2, X_3\)) cuenta estrictamente con dos valores posibles.
Tras alimentar a nuestro algoritmo de aprendizaje con este conjunto de datos, el resultado del entrenamiento es un modelo estructurado en forma de árbol. En ciencias de la computación, denominamos “árbol” a esta representación visual invertida que se ramifica de arriba hacia abajo.
Para familiarizarnos con la jerga técnica: cada uno de los elementos gráficos en forma de óvalo o rectángulo que componen la estructura recibe el nombre de nodo del árbol.
[ Nodo Raíz: Empleo Estable ]
/ \
(Sí: 4 ej.) (No: 6 ej.)
| \
[ Hoja: Aprobado ] [ Historial Crediticio ]
(4 de 4) / \
(Bueno: 2 ej.) (Malo: 4 ej.)
/ \
[ Nivel de Ingresos ] [ Hoja: Rechazado ]
/ \ (4 de 4)
(Altos: 1 ej.) (Bajos: 1 ej.)
/ \
[ Hoja: Aprobado ] [ Hoja: Rechazado ]
(1 de 1) (1 de 1)La forma en que funciona este modelo es que, si tienes un nuevo ejemplo de prueba con las siguientes características:
- historial crediticio bueno
- ingresos bajos
- sin empleo estable
Se empieza por el nodo superior, llamado nodo raíz, y se evalúa la característica elegida: el empleo estable. Como el cliente no tiene empleo estable, se va hacia la rama derecha, donde el árbol pregunta por el historial crediticio. Como el historial es bueno, se avanza hacia la izquierda y se llega a la última pregunta: el nivel de ingresos. Como los ingresos son bajos, se toma la rama derecha y el nodo hoja predice rechazar el préstamo.
El nodo situado en la parte superior del árbol se denomina nodo raíz. Todas las formas ovaladas se denominan nodos de decisión: observan una característica en particular y, basándose en su valor, deciden hacia dónde continuar. Por último, los nodos de la parte inferior (cajas rectangulares) se denominan nodos hoja. Hacen una predicción.
La función del algoritmo de aprendizaje del árbol de decisiones consiste, entre todos los árboles de decisión posibles, en tratar de elegir uno que dé buenos resultados en el conjunto de entrenamiento y, además, lo ideal es que también se generalice bien con datos nuevos, como los conjuntos de pruebas y validaciones cruzadas.
Para la gran mayoría de problemas basados en datos tabulares, la elección estándar en la industria suele decantarse por los conjuntos de árboles, siendo XGBoost la herramienta que predomina.
2 El proceso de aprendizaje en un árbol de decisión
La construcción de un árbol de decisiones a partir de un conjunto de entrenamiento se lleva a cabo mediante un proceso secuencial de particionamiento.
Partimos de un conjunto de 10 ejemplos que incluyen tanto solicitudes de préstamo aprobadas como rechazadas. El primer paso consiste en determinar qué característica utilizar en el nodo raíz, que es el punto de partida en la parte superior del árbol. Como veremos en la siguiente sección, el criterio es elegir la característica que deje las particiones más puras. En este dataset, esa característica es el empleo estable.
Seleccionamos el empleo estable como la característica principal y dividimos todos los datos de entrenamiento en función de sus valores:
- Enviamos los 4 ejemplos con empleo estable hacia la rama izquierda.
- Enviamos los 6 ejemplos sin empleo estable hacia la rama derecha.
[ Nodo Raíz: Empleo Estable ]
/ \
(Sí: 4 ej.) (No: 6 ej.)Al analizar el subconjunto de la izquierda (los 4 ejemplos con empleo estable), observamos que en su totalidad son préstamos aprobados. Por lo tanto, en lugar de seguir dividiendo, creamos un nodo hoja que predice directamente la aprobación.
Por el contrario, la rama derecha (6 ejemplos sin empleo estable) sigue mezclada: contiene 1 aprobado y 5 rechazados. El segundo paso consiste en decidir qué característica utilizar para seguir subdividiendo este subconjunto. Repitiendo el mismo criterio (maximizar la pureza), la mejor opción es el historial crediticio. Tomamos esos 6 ejemplos y los separamos según su valor:
- Los 2 ejemplos con buen historial van hacia la izquierda.
- Los 4 ejemplos con mal historial van hacia la derecha.
[ Nodo Raíz: Empleo Estable ]
/ \
(Sí: 4 ej.) (No: 6 ej.)
|
[ Historial Crediticio ]
/ \
(Bueno: 2 ej.) (Malo: 4 ej.)Los 4 ejemplos con mal historial son todos préstamos rechazados, así que se convierten en un nodo hoja que predice el rechazo. Los 2 ejemplos con buen historial (uno aprobado y uno rechazado) todavía están mezclados, por lo que necesitamos una última división, esta vez por nivel de ingresos:
- El ejemplo con ingresos altos va hacia la izquierda y, al ser un préstamo aprobado, se convierte en un nodo hoja que predice la aprobación.
- El ejemplo con ingresos bajos va hacia la derecha y, al ser un préstamo rechazado, se convierte en un nodo hoja que predice el rechazo.
[ Nodo Raíz: Empleo Estable ]
/ \
(Sí: 4 ej.) (No: 6 ej.)
|
[ Historial Crediticio ]
/ \
(Bueno: 2 ej.) (Malo: 4 ej.)
/ \
[ Nivel de Ingresos ] [ Hoja: Rechazado ]
/ \ (4 de 4)
(Altos: 1 ej.) (Bajos: 1 ej.)
/ \
[ Hoja: Aprobado ] [ Hoja: Rechazado ]
(1 de 1) (1 de 1)Con esto, todos los nodos hoja del árbol son puros: cada partición final contiene ejemplos de una única clase.
Durante este proceso de construcción, el algoritmo debe resolver dos decisiones fundamentales:
- ¿Cómo elegir la característica de división en cada nodo?
- ¿Cuándo detener el crecimiento del árbol?
3 Medición de la Pureza y la Entropía
Para construir un árbol de decisión, se necesita una métrica cuantitativa que evalúe la impureza o el grado de mezcla de clases en un conjunto de datos.
Supongamos un conjunto de seis solicitudes de crédito compuestas por tres préstamos aprobados (\(Y = 1\)) y tres préstamos rechazados (\(Y = 0\)). Definimos \(p_1\) como la proporción de ejemplos positivos (solicitudes aprobadas), es decir, la fracción de instancias con etiqueta \(1\). En este escenario inicial, \(p_1 = \frac{3}{6} = 0.5\).
Para medir la impureza de esta partición, utilizamos la función de Entropía de Shannon, denotada como \(H(p_1)\):
\[H(p_1) = -p_1 \log_2(p_1) - p_0 \log_2(p_0)\]
Donde \(p_0\) representa la proporción de ejemplos negativos (solicitudes rechazadas), calculada como \(p_0 = 1 - p_1\).
La Entropía de Shannon es un valor que va de 0 a 1, donde 1 representa la máxima impureza y 0 la máxima pureza.
- Cuando el conjunto está perfectamente equilibrado (\(p_1 = 0.5\), una mezcla de 50% aprobados y 50% rechazados), la incertidumbre es máxima y la entropía alcanza su pico con un valor de \(1\).
- Cuando el conjunto es homogéneo (contiene únicamente préstamos aprobados, \(p_1 = 1\), o únicamente rechazados, \(p_1 = 0\)), la entropía desciende a \(0\), indicando una pureza absoluta.
Imagina que evaluamos dos posibles divisiones. En la bifurcación izquierda, la proporción de ejemplos positivos es de \(0.8\), mientras que en la derecha es de \(0.2\). Al aplicar la función de entropía, obtenemos un valor de \(0.72\) para ambas ramas.Esto significa que ambas opciones presentan el mismo grado de impureza. Dado que la entropía en este punto se encuentra relativamente cerca del valor máximo de \(1\) (en lugar de aproximarse a \(0\)), esto nos indica que las particiones siguen siendo bastante heterogéneas y contienen una mezcla significativa de ambas clases.
| ID del Cliente | \(X_1\) (Historial) | \(X_2\) (Ingresos) | \(X_3\) (Empleo) | \(Y\) (Aprobado) |
|---|---|---|---|---|
| 1 | Bueno | Altos | Sí | 1 |
| 2 | Bueno | Altos | Sí | 1 |
| 3 | Bueno | Altos | No | 1 |
| 4 | Bueno | Bajos | Sí | 1 |
| 5 | Bueno | Bajos | No | 0 |
| 6 | Malo | Altos | Sí | 1 |
| 7 | Malo | Altos | No | 0 |
| 8 | Malo | Altos | No | 0 |
| 9 | Malo | Bajos | No | 0 |
| 10 | Malo | Bajos | No | 0 |
Analicemos qué tan pura queda cada partición según la característica elegida:
Si dividimos por Empleo Estable (\(X_3\))
- Rama Izquierda (Empleo = Sí):
- 4 ejemplos en total \(\rightarrow\) 4 aprobados y 0 rechazados (\(p_1 = 4/4 = 1.0\)).
- Entropía: \(H(1.0) = \mathbf{0.0}\) (grupo totalmente puro).
- Rama Derecha (Empleo = No):
- 6 ejemplos en total \(\rightarrow\) 1 aprobado y 5 rechazados (\(p_1 = 1/6 \approx 0.167\)).
- Entropía: \(H(0.167) = -0.167 \log_2(0.167) - 0.833 \log_2(0.833) = \mathbf{0.650}\)
Si dividimos por Historial Crediticio (\(X_1\))
- Rama Izquierda (Historial = Bueno):
- 5 ejemplos en total \(\rightarrow\) 4 aprobados y 1 rechazado (\(p_1 = 4/5 = 0.8\)).
- Entropía: \(H(0.8) = -0.8 \log_2(0.8) - 0.2 \log_2(0.2) = \mathbf{0.722}\)
- Rama Derecha (Historial = Malo):
- 5 ejemplos en total \(\rightarrow\) 1 aprobado y 4 rechazados (\(p_1 = 1/5 = 0.2\)).
- Entropía: \(H(0.2) = -0.2 \log_2(0.2) - 0.8 \log_2(0.8) = \mathbf{0.722}\)
Si dividimos por Nivel de Ingresos (\(X_2\))
- Rama Izquierda (Ingresos = Altos):
- 6 ejemplos en total \(\rightarrow\) 4 aprobados y 2 rechazados (\(p_1 = 4/6 \approx 0.67\)).
- Entropía: \(H(0.67) = -0.67 \log_2(0.67) - 0.33 \log_2(0.33) = \mathbf{0.918}\)
- Rama Derecha (Ingresos = Bajos):
- 4 ejemplos en total \(\rightarrow\) 1 aprobado y 3 rechazados (\(p_1 = 1/4 = 0.25\)).
- Entropía: \(H(0.25) = -0.25 \log_2(0.25) - 0.75 \log_2(0.75) = \mathbf{0.811}\)
El promedio ponderado de la entropía se utiliza para medir cuánto caos o incertidumbre queda en total después de dividir un conjunto de datos utilizando una característica específica.
\[\text{Entropía Ponderada} = \left( \frac{\text{Ejemplos en Izquierda}}{\text{Total de Ejemplos}} \times \text{Entropía Izquierda} \right) + \left( \frac{\text{Ejemplos en Derecha}}{\text{Total de Ejemplos}} \times \text{Entropía Derecha} \right)\]
| Característica evaluada | Rama Izquierda (Muestras / Entropía) | Rama Derecha (Muestras / Entropía) | Promedio Ponderado de Entropía | Decisión / Resultado |
|---|---|---|---|---|
| 1. Empleo Estable (\(X_3\)) | 4 muestras - Entropía: 0.000 (100% puro) | 6 muestras - Entropía: 0.650 | \((0.4 \times 0.0) + (0.6 \times 0.650) = \mathbf{0.390}\) | Ganadora (La que deja menos caos) |
| 2. Historial Crediticio (\(X_1\)) | 5 muestras - Entropía: 0.722 | 5 muestras - Entropía: 0.722 | \((0.5 \times 0.722) + (0.5 \times 0.722) = \mathbf{0.722}\) | Segunda opción |
| 3. Nivel de Ingresos (\(X_2\)) | 6 muestras - Entropía: 0.918 | 4 muestras - Entropía: 0.811 | \((0.6 \times 0.918) + (0.4 \times 0.811) = \mathbf{0.875}\) | Menos efectiva (Deja el conjunto muy caótico) |
4 Ganancia de Información (Information Gain)
El objetivo al dividir un nodo es encontrar la característica (por ejemplo: historial crediticio, nivel de ingresos o empleo estable) que maximice la reducción de la entropía (es decir, que maximice la pureza de los subconjuntos resultantes). En el aprendizaje de árboles de decisión, esta reducción se conoce formalmente como Ganancia de Información.
La Ganancia de Información se define matemáticamente como la diferencia entre la entropía del nodo padre (antes de la división) y la entropía promedio ponderada de los nodos hijos (después de la división):
\[\text{Ganancia} = H(p_1^{\text{root}}) - \left( w^{\text{left}} H(p_1^{\text{left}}) + w^{\text{right}} H(p_1^{\text{right}}) \right)\]
Donde:
- \(H(p_1^{\text{root}})\) es la entropía del nodo actual.
- \(w^{\text{left}}\) y \(w^{\text{right}}\) son las proporciones de solicitudes que van a la rama izquierda y derecha, respectivamente.
- \(H(p_1^{\text{left}})\) y \(H(p_1^{\text{right}})\) son las entropías de los subconjuntos hijos.
\[\text{Ganancia de Información} = H(\text{root}) - \text{Entropía Ponderada}\]
El algoritmo evaluará todas las características disponibles y seleccionará aquella que genere la mayor ganancia de información (la mayor reducción neta de impureza).
Dado que en nuestro nodo raíz (con 5 préstamos aprobados y 5 rechazados) la entropía inicial es máxima, tenemos que:
\[H(\text{root}) = 1.000\]
A partir de los promedios ponderados de entropía que calculamos anteriormente para cada característica, los cálculos de la ganancia de información son los siguientes:
| Característica Evaluada | Entropía del Nodo Padre (\(H(\text{root})\)) | Entropía Promedio Ponderada | Cálculo de la Ganancia de Información | Resultado (Ganancia) | Decisión del Algoritmo |
|---|---|---|---|---|---|
| 1. Empleo Estable (\(X_3\)) | 1.000 | 0.390 | \(1.000 - 0.390\) | 0.610 | Ganadora (Mayor reducción de caos) |
| 2. Historial Crediticio (\(X_1\)) | 1.000 | 0.722 | \(1.000 - 0.722\) | 0.278 | Descartada |
| 3. Nivel de Ingresos (\(X_2\)) | 1.000 | 0.875 | \(1.000 - 0.875\) | 0.125 | Descartada |
Una vez que comprendemos cómo calcular la Ganancia de Información, podemos aplicar este criterio de forma repetitiva a lo largo de todo el conjunto de datos para construir un árbol de decisión completo con múltiples nodos.
El algoritmo general de construcción sigue estos pasos:
- Inicialización: Se comienza con la totalidad de los ejemplos de entrenamiento ubicados en el nodo raíz.
- Evaluación: Se calcula la ganancia de información para todas las características disponibles en el nodo actual.
- Selección y División: Se selecciona la característica que ofrece la mayor ganancia de información. El conjunto de datos se divide en dos subconjuntos (ramas izquierda y derecha) según el valor que toma dicha característica en cada instancia.
- Recursión: El proceso se repite de manera idéntica para cada una de las subramas generadas, tratándolas como nuevos nodos raíz independientes formados por subconjuntos de datos más reducidos.
- Criterios de Parada: Las divisiones sucesivas continúan hasta que se cumple al menos una condición de detención.
Para evitar que el árbol crezca indefinidamente o capture ruido estadístico, se establecen criterios de parada que determinan cuándo un nodo se convierte en un nodo hoja (nodo terminal que emite una predicción definitiva). Estos criterios incluyen:
- Pureza Absoluta: Un nodo alcanza una entropía de \(0\) (todas las muestras pertenecen a una única clase).
- Profundidad Máxima (
max_depth): Se alcanza el límite preestablecido de niveles en el árbol. - Ganancia Insuficiente: La reducción de entropía obtenida al realizar una división adicional cae por debajo de un umbral mínimo determinado.
- Muestra Mínima: El número de ejemplos en un nodo es inferior a un umbral crítico, lo que desaconseja nuevas particiones por falta de soporte estadístico.
Uno de los hiperparámetros más importantes al entrenar un árbol de decisión es la profundidad máxima:
- Mayor profundidad: Permite al modelo aprender patrones más complejos y detallados (un comportamiento conceptualmente análogo a entrenar un polinomio de grado superior o una red neuronal más grande).
- Riesgo: Un árbol excesivamente profundo incrementa de forma drástica el riesgo de sobreajuste (overfitting), memorizando el ruido del conjunto de entrenamiento en lugar de generalizar.
Hasta ahora hemos usado características con solo dos opciones (como Sí/No o Bueno/Malo). Pero ¿qué pasa si una característica tiene más de dos valores posibles?
5 Características no binarias
Imaginemos que modificamos la característica de Nivel de Ingresos para que ya no sea solo binaria (Altos / Bajos), sino que tenga tres categorías (\(k = 3\)): Bajos, Medios y Altos.
Si tuviéramos un cliente con ingresos Medios, la columna de ingresos se vería así:
| ID del Cliente | Nivel de Ingresos (Original) | Préstamo Aprobado (\(Y\)) |
|---|---|---|
| 1 | Altos | 1 |
| 2 | Medios | 1 |
| 3 | Bajos | 0 |
Para un árbol de decisión, manejar una sola columna con tres textos diferentes obliga a hacer divisiones múltiples complejas en una sola rama. Aquí es donde entra la Codificación One-Hot.
En lugar de tener una sola columna con tres opciones, la descomponemos en tres características binarias independientes (una por cada categoría), donde cada una solo aceptará los valores 0 o 1:
Ingresos_Bajos: Vale \(1\) si es bajo, \(0\) en cualquier otro caso.Ingresos_Medios: Vale \(1\) si es medio, \(0\) en cualquier otro caso.Ingresos_Altos: Vale \(1\) si es alto, \(0\) en cualquier otro caso.
Si aplicamos esta transformación a nuestros clientes de ejemplo, la tabla se ve así:
| ID del Cliente | Ingresos_Bajos | Ingresos_Medios | Ingresos_Altos | Préstamo Aprobado (\(Y\)) |
|---|---|---|---|---|
| 1 | 0 | 0 | 1 | 1 |
| 2 | 0 | 1 | 0 | 1 |
| 3 | 1 | 0 | 0 | 0 |
Nota por qué se llama “One-Hot” (un bit encendido): Observa que en cada fila, exactamente una de las tres columnas tiene el valor 1 (encendida) y las demás tienen 0 (apagadas).
6 Características continuas
Hasta ahora hemos trabajado con características categóricas (valores discretos como Sí/No o Altos/Bajos). Sin embargo, ¿qué ocurre si una característica es continua, es decir, un número que puede tomar cualquier valor dentro de un rango (como el peso, la temperatura o la edad)?
Para entenderlo, imaginemos que añadimos a nuestro conjunto de datos de préstamos una nueva característica continua: el Sueldo en miles de euros. A diferencia de las categorías fijas, un sueldo puede ser 25.5, 30.2, 45.0, etc.
Un árbol de decisión no puede crear una rama por cada número decimal existente. En su lugar, el algoritmo convierte la característica continua en una pregunta de tipo binario basada en un umbral (\(\le\) o \(>\)).
La pregunta clave que el algoritmo debe resolver es: ¿Cuál es el mejor número (umbral) para cortar los datos?
Para encontrar el punto de corte ideal en una característica continua, el algoritmo sigue estos pasos:
- Ordenar los datos: Se toman todos los ejemplos de entrenamiento y se ordenan de menor a mayor según el valor de esa característica continua.
- Probar múltiples puntos de corte (umbrales): El algoritmo evalúa diferentes valores posibles para dividir los datos. Por lo general, una convención muy práctica es probar los puntos medios entre los valores de la lista ordenada. Si tienes 10 ejemplos, probará 9 posibles umbrales diferentes.
- Calcular la Ganancia de Información para cada umbral: Para cada número que prueba, divide los datos en dos grupos (\(\le \text{umbral}\) y \(> \text{umbral}\)) y calcula cuánta ganancia de información se obtiene.
- Seleccionar el mejor: El algoritmo se queda con el umbral que genere la mayor ganancia de información.
Imaginemos que probamos tres umbrales diferentes para el sueldo de nuestros clientes:
- Prueba 1 (Sueldo \(\le 30\) mil €): Al hacer la división, la ganancia de información resultante es baja: \(0.24\).
- Prueba 2 (Sueldo \(\le 40\) mil €): Al probar este umbral, la ganancia de información sube considerablemente a \(0.61\) (separa muy bien a los que pagan de los que no).
- Prueba 3 (Sueldo \(\le 55\) mil €): La ganancia baja a \(0.40\).
Como el umbral de \(40\) mil € es el que proporciona la mayor ganancia de información (\(0.61\)), el algoritmo lo selecciona como la regla de división óptima para esa característica continua.
A partir de ahí, si este valor supera a cualquier otra característica evaluada en el nodo, la regla final del nodo será: ¿El sueldo es \(\le 40\) mil €? (Sí / No), dividiendo los datos en dos subramas y continuando el proceso de forma recursiva.
7 Árboles de Decisión para Regresión
Hasta ahora hemos estudiado los árboles de decisión como modelos de clasificación (donde la variable objetivo \(Y\) es una categoría, como Aprobado/Rechazado o Perro/Gato).
Sin embargo, los árboles de decisión se pueden generalizar a problemas de regresión, donde el objetivo es predecir un valor numérico continuo \(Y\) (por ejemplo, el peso de un animal, el precio de una vivienda o el monto asignado a un préstamo).
En un problema de clasificación, el nodo hoja predice la clase mayoritaria. En un problema de regresión, el nodo hoja hace su predicción calculando la media (promedio) de los valores \(Y\) de los ejemplos de entrenamiento que llegaron a ese nodo.
Si tras la división de ramas, un nodo hoja agrupa cuatro ejemplos con valores de \(7.2\), \(7.6\), \(8.4\) y \(10.2\) euros, la predicción del modelo para cualquier nuevo dato de prueba que caiga en este nodo será el promedio de esos valores:
\[\text{Predicción} = \frac{7.2 + 7.6 + 8.4 + 10.2}{4} = 8.35\text{ €}\]
Al construir un árbol de regresión, no podemos usar la Entropía como medida de impureza, ya que los valores de salida no son categorías binarias sino números. En su lugar, utilizamos la Varianza, que mide qué tan dispersos están los valores numéricos dentro de un nodo.
El objetivo al dividir un nodo en regresión es minimizar la varianza de las ramas hijas, logrando agrupaciones con valores lo más homogéneos posible.
El equivalente a la Ganancia de Información se denomina Reducción de la Varianza, y se define como:
\[\text{Reducción de Varianza} = Var(\text{nodo padre}) - \text{Varianza Promedio Ponderada de las ramas}\]
En lugar de predecir si el préstamo es Aprobado (1) o Rechazado (0) (clasificación), ahora queremos predecir el número continuo \(Y\): Monto del Préstamo Aprobado (en miles de €).
Imaginemos que tenemos los siguientes datos de entrenamiento donde medimos la característica Empleo Estable (\(X_3\)) frente al monto concedido:
| Cliente | Empleo Estable (\(X_3\)) | Monto del Préstamo \(Y\) (en miles de €) |
|---|---|---|
| 1 | Sí | 70 |
| 2 | Sí | 80 |
| 3 | Sí | 90 |
| 4 | Sí | 100 |
| 5 | No | 10 |
| 6 | No | 15 |
| 7 | No | 20 |
| 8 | No | 10 |
| 9 | No | 25 |
| 10 | No | 10 |
Si dividimos por la característica Empleo Estable (\(X_3\)), obtenemos dos ramas. Como es un problema de regresión, la predicción para cualquier cliente nuevo en esa rama será la media (promedio) de su grupo:
- Rama Izquierda (Empleo = Sí):
- Clientes: 1, 2, 3, 4.
- Montos: [70, 80, 90, 100]
- Predicción del nodo: \(\frac{70 + 80 + 90 + 100}{4} = \mathbf{85\text{ mil €}}\)
- Rama Derecha (Empleo = No):
- Clientes: 5, 6, 7, 8, 9, 10.
- Montos: [10, 15, 20, 10, 25, 10]
- Predicción del nodo: \(\frac{10 + 15 + 20 + 10 + 25 + 10}{6} = \mathbf{15\text{ mil €}}\)
Para saber si Empleo Estable es una buena división frente a Historial Crediticio o Nivel de Ingresos, calculamos la Reducción de Varianza:
- Varianza en el Nodo Raíz (Antes de dividir): Con los 10 datos mezclados (de 10 mil a 100 mil €), la varianza inicial es muy alta:
\[Var(\text{raíz}) = 1247\]
- Varianza en los Nodos Hijos (Después de dividir):
- Rama Izquierda: Los datos están muy juntos (entre 70 y 100). \(Var(\text{izq}) = 125\)
- Rama Derecha: Los datos también están agrupados abajo (entre 10 y 25). \(Var(\text{der}) = 33.33\)
- Varianza Promedio Ponderada:
\[\text{Varianza Ponderada} = \left( \frac{4}{10} \times 125 \right) + \left( \frac{6}{10} \times 33.33 \right) = 50 + 20 = \mathbf{70}\]
- Reducción Neta de Varianza:
\[\text{Reducción} = 1247 - 70 = \mathbf{1177}\]
| Característica Evaluada | Varianza del Nodo Raíz | Varianza Promedio Ponderada | Reducción de Varianza (\(Var(\text{raíz}) - Var(\text{hijos})\)) | Decisión del Algoritmo |
|---|---|---|---|---|
| 1. Empleo Estable (\(X_3\)) | 1247 | 70 | 1177 | Ganadora (Mayor reducción de varianza) |
| 2. Historial Crediticio (\(X_1\)) | 1247 | 540 | 707 | Descartada |
| 3. Nivel de Ingresos (\(X_2\)) | 1247 | 810 | 437 | Descartada |
Al igual que en clasificación elegíamos la característica que maximizaba la Ganancia de Información (entropía), en regresión el árbol elige la característica que maximiza la Reducción de la Varianza (1177), seleccionando Empleo Estable como el nodo raíz.
8 Implementación con scikit-learn
Para cerrar el capítulo, implementemos el árbol de decisión del ejemplo de préstamos con scikit-learn. Como las tres características son categóricas, aplicamos una codificación one-hot y entrenamos un DecisionTreeClassifier con el criterio de entropía:
#| eval: false
#| message: false
import pandas as pd
from sklearn.tree import DecisionTreeClassifier, export_text
from sklearn.preprocessing import OneHotEncoder
data = pd.DataFrame({
"historial": ["Bueno", "Bueno", "Bueno", "Bueno", "Bueno",
"Malo", "Malo", "Malo", "Malo", "Malo"],
"ingresos": ["Altos", "Altos", "Altos", "Bajos", "Bajos",
"Altos", "Altos", "Altos", "Bajos", "Bajos"],
"empleo": ["Si", "Si", "No", "Si", "No",
"Si", "No", "No", "No", "No"],
"aprobado": [1, 1, 1, 1, 0, 1, 0, 0, 0, 0],
})
X = OneHotEncoder().fit_transform(data[["historial", "ingresos", "empleo"]])
y = data["aprobado"]
arbol = DecisionTreeClassifier(criterion="entropy", max_depth=3, random_state=42)
arbol.fit(X, y)
print(export_text(arbol, feature_names=["historial_Bueno", "historial_Malo",
"ingresos_Altos", "ingresos_Bajos",
"empleo_Si", "empleo_No"]))El árbol resultante replica exactamente la estructura que hemos construido a mano: la primera división se hace por empleo estable (entropía), seguida del historial crediticio y, en la rama impura restante, del nivel de ingresos.