Los métodos como los árboles de decisión pueden ser propensos a sobreajustarse en el conjunto de entrenamiento, lo que puede conducir a predicciones incorrectas sobre nuevos datos.
Bootstrap Aggregation (bagging) es un método de ensamblaje que intenta resolver el sobreajuste para problemas de clasificación o regresión. El embolsado tiene como objetivo mejorar la precisión y el rendimiento de los algoritmos de aprendizaje automático. Lo hace tomando subconjuntos aleatorios de un conjunto de datos original, con reemplazo, y ajusta un clasificador (para clasificación) o un regresor (para regresión) a cada subconjunto. Luego, las predicciones para cada subconjunto se agregan a través del voto mayoritario para la clasificación o el promedio para la regresión, lo que aumenta la precisión de la predicción.
Evaluación de un clasificador base
Para ver cómo el embolsado puede mejorar el rendimiento del modelo, debemos comenzar evaluando cómo se desempeña el clasificador base en el conjunto de datos. Si no sabe qué son los árboles de decisión, revise la lección sobre árboles de decisión antes de seguir adelante, ya que el embolsado es una continuación del concepto.
Buscaremos identificar las diferentes clases de vinos que se encuentran en el conjunto de datos de vinos de Sklearn.
Empecemos importando los módulos necesarios.
from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score from sklearn.tree import DecisionTreeClassifier
A continuación, debemos cargar los datos y almacenarlos en X (características de entrada) e y (objetivo). El parámetro as_frame se establece igual a True para que no perdamos los nombres de las funciones al cargar los datos. (La versión de sklearn anterior a 0.23 debe omitir el argumento as_frame ya que no es compatible)
data = datasets.load_wine(as_frame = True)
X = data.data
y = data.target
Para evaluar correctamente nuestro modelo en datos no vistos, necesitamos dividir X e Y en conjuntos de entrenamiento y prueba. Para obtener información sobre la división de datos, consulte la lección Entrenar/Prueba.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 22)
Con nuestros datos preparados, ahora podemos instanciar un clasificador base y ajustarlo a los datos de entrenamiento.
dtree = DecisionTreeClassifier(random_state = 22)
dtree.fit(X_train,y_train)
Resultado:
DecisionTreeClassifier(random_state=22)
Ahora podemos predecir la clase de vino del conjunto de prueba invisible y evaluar el rendimiento del modelo.
y_pred = dtree.predict(X_test) print("Train data accuracy:",accuracy_score(y_true = y_train, y_pred = dtree.predict(X_train))) print("Test data accuracy:",accuracy_score(y_true = y_test, y_pred = y_pred))
Resultado
Train data accuracy: 1.0 Test data accuracy: 0.8222222222222222
Ejemplo
Importe los datos necesarios y evalúe el rendimiento del clasificador base.
from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score from sklearn.tree import DecisionTreeClassifier data = datasets.load_wine(as_frame = True) X = data.data y = data.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 22) dtree = DecisionTreeClassifier(random_state = 22) dtree.fit(X_train,y_train) y_pred = dtree.predict(X_test) print("Train data accuracy:",accuracy_score(y_true = y_train, y_pred = dtree.predict(X_train))) print("Test data accuracy:",accuracy_score(y_true = y_test, y_pred = y_pred))
El clasificador base se desempeña razonablemente bien en el conjunto de datos logrando un 82 % de precisión en el conjunto de datos de prueba con los parámetros actuales (pueden ocurrir diferentes resultados si no tiene configurado el parámetro random_state).
Ahora que tenemos una precisión de línea de base para el conjunto de datos de prueba, podemos ver cómo el clasificador de embolsado realiza un solo clasificador de árbol de decisión.
Creación de un clasificador de embolsado
Para empaquetar necesitamos establecer el parámetro n_estimators, este es el número de clasificadores base que nuestro modelo agregará.
Para este conjunto de datos de muestra, el número de estimadores es relativamente bajo, a menudo ocurre que se exploran rangos mucho más grandes. El ajuste de hiperparámetros generalmente se realiza con una búsqueda en cuadrícula, pero por ahora usaremos un conjunto seleccionado de valores para el número de estimadores.
Comenzamos importando el modelo necesario.
from sklearn.ensemble import BaggingClassifier
Ahora vamos a crear un rango de valores que representen el número de estimadores que queremos usar en cada conjunto.
estimator_range = [2,4,6,8,10,12,14,16]
Para ver cómo funciona el clasificador de bolsas con diferentes valores de n_estimators, necesitamos una forma de iterar sobre el rango de valores y almacenar los resultados de cada conjunto. Para ello crearemos un bucle for, almacenando los modelos y puntuaciones en listas separadas para visualizaciones posteriores.
Nota: El parámetro predeterminado para el clasificador base en BaggingClassifier es DicisionTreeClassifier, por lo que no es necesario establecerlo al crear una instancia del modelo de embolsado.
models = [] scores = [] for n_estimators in estimator_range: # Create bagging classifier clf = BaggingClassifier(n_estimators = n_estimators, random_state = 22) # Fit the model clf.fit(X_train, y_train) # Append the model and score to their respective list models.append(clf) scores.append(accuracy_score(y_true = y_test, y_pred = clf.predict(X_test)))
Con los modelos y puntajes almacenados, ahora podemos visualizar la mejora en el rendimiento del modelo.
import matplotlib.pyplot as plt # Generate the plot of scores against number of estimators plt.figure(figsize=(9,6)) plt.plot(estimator_range, scores) # Adjust labels and font (to make visable) plt.xlabel("n_estimators", fontsize = 18) plt.ylabel("score", fontsize = 18) plt.tick_params(labelsize = 18) # Visualize plot plt.show()
Ejemplo
Importe los datos necesarios y evalúe el rendimiento de BaggingClassifier.
import matplotlib.pyplot as plt from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score from sklearn.ensemble import BaggingClassifier data = datasets.load_wine(as_frame = True) X = data.data y = data.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 22) estimator_range = [2,4,6,8,10,12,14,16] models = [] scores = [] forin# Create bagging classifier clf = BaggingClassifier(n_estimators = n_estimators, random_state = 22) # Fit the model clf.fit(X_train, y_train) # Append the model and score to their respective list models.append(clf) scores.append(accuracy_score(y_true = y_test, y_pred = clf.predict(X_test))) # Generate the plot of scores against number of estimators plt.figure(figsize=(9.6)) plt.plot(estimator_range, scores) # Adjust labels and font (to make visable) plt.xlabel("n_estimators", fontsize = 18) plt.ylabel("score", fontsize = 18) plt.tick_params(labelsize = 16) # Visualize plot plt.show()
Resultados explicados
Al iterar a través de diferentes valores para el número de estimadores, podemos ver un aumento en el rendimiento del modelo del 82,2 % al 95,5 %. Después de 14 estimadores, la precisión comienza a disminuir; nuevamente, si establece un estado aleatorio diferente, los valores que ve variarán. Es por eso que es una buena práctica utilizar la validación cruzada para garantizar resultados estables.
En este caso, vemos un aumento del 13,3% en la precisión a la hora de identificar el tipo de vino.
Otra forma de evaluación
Dado que el bootstrapping elige subconjuntos aleatorios de observaciones para crear clasificadores, hay observaciones que quedan fuera del proceso de selección. Estas observaciones «listas para usar» se pueden usar para evaluar el modelo, de manera similar a las de un conjunto de prueba. Tenga en cuenta que la estimación directa puede sobrestimar el error en los problemas de clasificación binaria y solo debe usarse como complemento de otras métricas.
Vimos en el último ejercicio que 12 estimadores arrojaron la mayor precisión, por lo que usaremos eso para crear nuestro modelo. Esta vez configurando el parámetro oob_score en verdadero para evaluar el modelo con puntaje fuera de la bolsa.
Ejemplo
Cree un modelo con métrica fuera de bolsa.
from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.ensemble import BaggingClassifier data = datasets.load_wine(as_frame = True) X = data.data y = data.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 22) oob_model = BaggingClassifier(n_estimators = 12, oob_score = True,random_state = 22) oob_model.fit(X_train, y_train) print(oob_model.oob_score_)
Dado que las muestras utilizadas en OOB y el conjunto de prueba son diferentes y el conjunto de datos es relativamente pequeño, existe una diferencia en la precisión. Es raro que sean exactamente iguales, nuevamente OOB debe usarse como un medio rápido para estimar el error, pero no es la única métrica de evaluación.
Generación de árboles de decisión a partir del clasificador de embolsado
Como se vio en la lección Árbol de decisión, es posible graficar el árbol de decisión que creó el modelo. También es posible ver los árboles de decisión individuales que entraron en el clasificador agregado. Esto nos ayuda a obtener una comprensión más intuitiva de cómo el modelo de embolsado llega a sus predicciones.
Nota: Esto solo funciona con conjuntos de datos más pequeños, donde los árboles son relativamente poco profundos y angostos, lo que los hace fáciles de visualizar.
Tendremos que importar la función plot_tree de sklearn.tree. Los diferentes árboles se pueden graficar cambiando el estimador que desea visualizar.
Ejemplo
from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.ensemble import BaggingClassifier from sklearn.tree import plot_tree X = data.data y = data.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 22) clf = BaggingClassifier(n_estimators = 12, oob_score = True,random_state = 22) clf.fit(X_train, y_train) plt.figure(figsize=(30, 20)) plot_tree(clf.estimators_[0], feature_names = X.columns)
Aquí podemos ver solo el primer árbol de decisiones que se usó para votar sobre la predicción final. Nuevamente, al cambiar el índice del clasificador, puede ver cada uno de los árboles que se han agregado.