Árboles de decisión potenciados con AdaBoost para múltiples clases

Beginner

This tutorial is from open-source community. Access the source code

Introducción

En este laboratorio, exploraremos cómo el boosting puede mejorar la precisión de predicción en un problema de múltiples clases. Utilizaremos un conjunto de datos construido a partir de una distribución normal estándar de diez dimensiones y definiendo tres clases separadas por esferas concéntricas de diez dimensiones anidadas de modo que aproximadamente iguales cantidades de muestras estén en cada clase.

Compararemos el rendimiento de los algoritmos SAMME y SAMME.R. SAMME.R utiliza las estimaciones de probabilidad para actualizar el modelo aditivo, mientras que SAMME utiliza solo las clasificaciones.

Consejos sobre la VM

Una vez finalizada la inicialización de la VM, haga clic en la esquina superior izquierda para cambiar a la pestaña Cuaderno y acceder a Jupyter Notebook para practicar.

A veces, es posible que tenga que esperar unos segundos a que Jupyter Notebook termine de cargarse. La validación de operaciones no puede automatizarse debido a las limitaciones de Jupyter Notebook.

Si tiene problemas durante el aprendizaje, no dude en preguntar a Labby. Deje sus comentarios después de la sesión y lo resolveremos rápidamente para usted.

Importar las bibliotecas necesarias

Comenzaremos importando las bibliotecas necesarias, incluyendo make_gaussian_quantiles y accuracy_score de sklearn.datasets, AdaBoostClassifier, DecisionTreeClassifier de sklearn.ensemble y matplotlib.pyplot.

import matplotlib.pyplot as plt
from sklearn.datasets import make_gaussian_quantiles
from sklearn.ensemble import AdaBoostClassifier
from sklearn.metrics import accuracy_score
from sklearn.tree import DecisionTreeClassifier

Cargar el conjunto de datos

Utilizaremos la función make_gaussian_quantiles de sklearn.datasets para generar un conjunto de datos. Esta función genera Gaussianas isotrópicas y agrega separación entre las clases para hacer el problema más difícil.

X, y = make_gaussian_quantiles(
    n_samples=13000, n_features=10, n_classes=3, random_state=1
)

Dividir el conjunto de datos

Dividiremos el conjunto de datos en conjuntos de entrenamiento y prueba, utilizando las primeras 3000 muestras para el entrenamiento y las muestras restantes para la prueba.

n_split = 3000
X_train, X_test = X[:n_split], X[n_split:]
y_train, y_test = y[:n_split], y[n_split:]

Crear y entrenar los modelos

Crearemos dos modelos de AdaBoost, uno que utilice SAMME y el otro que utilice SAMME.R. Ambos modelos utilizarán DecisionTreeClassifier con una profundidad máxima de 2 y 300 estimadores.

bdt_real = AdaBoostClassifier(
    DecisionTreeClassifier(max_depth=2), n_estimators=300, learning_rate=1
)

bdt_discrete = AdaBoostClassifier(
    DecisionTreeClassifier(max_depth=2),
    n_estimators=300,
    learning_rate=1.5,
    algorithm="SAMME",
)

bdt_real.fit(X_train, y_train)
bdt_discrete.fit(X_train, y_train)

Probar los modelos

Probaremos los modelos y calcularemos el error de prueba de cada modelo después de cada iteración de potenciación.

real_test_errors = []
discrete_test_errors = []

for real_test_predict, discrete_test_predict in zip(
    bdt_real.staged_predict(X_test), bdt_discrete.staged_predict(X_test)
):
    real_test_errors.append(1.0 - accuracy_score(real_test_predict, y_test))
    discrete_test_errors.append(1.0 - accuracy_score(discrete_test_predict, y_test))

Graficar los resultados

Graficaremos el error de prueba, el error de clasificación y el peso de potenciación de cada modelo.

n_trees_discrete = len(bdt_discrete)
n_trees_real = len(bdt_real)

## La potenciación puede terminar temprano, pero las siguientes matrices siempre
## son de longitud n_estimators. Las recortamos al número real de árboles aquí:
discrete_estimator_errors = bdt_discrete.estimator_errors_[:n_trees_discrete]
real_estimator_errors = bdt_real.estimator_errors_[:n_trees_real]
discrete_estimator_weights = bdt_discrete.estimator_weights_[:n_trees_discrete]

plt.figure(figsize=(15, 5))

plt.subplot(131)
plt.plot(range(1, n_trees_discrete + 1), discrete_test_errors, c="black", label="SAMME")
plt.plot(
    range(1, n_trees_real + 1),
    real_test_errors,
    c="black",
    linestyle="dashed",
    label="SAMME.R",
)
plt.legend()
plt.ylim(0.18, 0.62)
plt.ylabel("Error de prueba")
plt.xlabel("Número de árboles")

plt.subplot(132)
plt.plot(
    range(1, n_trees_discrete + 1),
    discrete_estimator_errors,
    "b",
    label="SAMME",
    alpha=0.5,
)
plt.plot(
    range(1, n_trees_real + 1), real_estimator_errors, "r", label="SAMME.R", alpha=0.5
)
plt.legend()
plt.ylabel("Error")
plt.xlabel("Número de árboles")
plt.ylim((0.2, max(real_estimator_errors.max(), discrete_estimator_errors.max()) * 1.2))
plt.xlim((-20, len(bdt_discrete) + 20))

plt.subplot(133)
plt.plot(range(1, n_trees_discrete + 1), discrete_estimator_weights, "b", label="SAMME")
plt.legend()
plt.ylabel("Peso")
plt.xlabel("Número de árboles")
plt.ylim((0, discrete_estimator_weights.max() * 1.2))
plt.xlim((-20, n_trees_discrete + 20))

## Evita etiquetas de eje y superpuestas
plt.subplots_adjust(wspace=0.25)
plt.show()

Resumen

En este laboratorio, exploramos cómo la potenciación puede mejorar la precisión de predicción en un problema de múltiples clases. Utilizamos un conjunto de datos construido tomando una distribución normal estándar de diez dimensiones y definiendo tres clases separadas por esferas concéntricas anidadas de diez dimensiones. Comparamos el rendimiento de los algoritmos SAMME y SAMME.R y graficamos el error de prueba, el error de clasificación y el peso de potenciación de cada modelo. Los resultados mostraron que SAMME.R generalmente converge más rápido que SAMME, logrando un error de prueba más bajo con menos iteraciones de potenciación.