Árvores de Decisão AdaBoostadas Multi-Classe

Beginner

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

Introdução

Neste laboratório, exploraremos como o boosting pode melhorar a precisão de previsão em um problema multiclasse. Usaremos um conjunto de dados construído a partir de uma distribuição normal padrão de dez dimensões, definindo três classes separadas por esferas concêntricas aninhadas de dez dimensões, de forma que aproximadamente o mesmo número de amostras esteja em cada classe.

Compararemos o desempenho dos algoritmos SAMME e SAMME.R. SAMME.R utiliza as estimativas de probabilidade para atualizar o modelo aditivo, enquanto SAMME utiliza apenas as classificações.

Dicas da Máquina Virtual

Após o término do arranque da VM, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para praticar.

Às vezes, pode ser necessário esperar alguns segundos para que o Jupyter Notebook termine de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se tiver problemas durante o aprendizado, sinta-se à vontade para perguntar ao Labby. Forneça feedback após a sessão e resolveremos prontamente o problema para si.

Importação de Bibliotecas Necessárias

Começaremos importando as bibliotecas necessárias, incluindo make_gaussian_quantiles e accuracy_score de sklearn.datasets, AdaBoostClassifier, DecisionTreeClassifier de sklearn.ensemble, e 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

Carregar o Conjunto de Dados

Usaremos a função make_gaussian_quantiles de sklearn.datasets para gerar um conjunto de dados. Esta função gera distribuições gaussianas isotrópicas e adiciona separação entre as classes para tornar o problema mais difícil.

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

Dividir o Conjunto de Dados

Dividiremos o conjunto de dados em conjuntos de treinamento e teste, utilizando os primeiros 3000 exemplos para treinamento e os exemplos restantes para teste.

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

Criar e Treinar os Modelos

Criaremos dois modelos AdaBoost, um usando SAMME e outro usando SAMME.R. Ambos os modelos utilizarão DecisionTreeClassifier com uma profundidade máxima de 2 e 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)

Testar os Modelos

Vamos testar os modelos e calcular o erro de teste de cada modelo após cada iteração de boosting.

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))

Plotar os Resultados

Vamos plotar o erro de teste, o erro de classificação e o peso de cada modelo.

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

## O boosting pode terminar antecipadamente, mas os arrays seguintes sempre
## têm o tamanho de n_estimators. Nós os cortamos para o número real de árvores aqui:
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("Erro de Teste")
plt.xlabel("Número de Árvores")

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("Erro")
plt.xlabel("Número de Árvores")
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 Árvores")
plt.ylim((0, discrete_estimator_weights.max() * 1.2))
plt.xlim((-20, n_trees_discrete + 20))

## evitar sobreposição das etiquetas do eixo y
plt.subplots_adjust(wspace=0.25)
plt.show()

Resumo

Neste laboratório, exploramos como o boosting pode melhorar a precisão de previsão em um problema multiclasse. Usamos um conjunto de dados construído a partir de uma distribuição normal padrão de dez dimensões, definindo três classes separadas por esferas concêntricas aninhadas de dez dimensões. Comparamos o desempenho dos algoritmos SAMME e SAMME.R e plotamos o erro de teste, o erro de classificação e o peso de reforço de cada modelo. Os resultados mostraram que o SAMME.R geralmente converge mais rapidamente que o SAMME, alcançando um erro de teste menor com menos iterações de boosting.