Plotagem de Curvas de Aprendizagem

Beginner

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

Introdução

O objetivo deste laboratório é mostrar como usar a classe LearningCurveDisplay do scikit-learn para plotar curvas de aprendizado. As curvas de aprendizado mostram o efeito de adicionar mais amostras durante o processo de treinamento. Analisaremos a curva de aprendizado de um classificador Naive Bayes e um classificador SVM com um kernel RBF usando o conjunto de dados dígitos. Além disso, analisaremos a escalabilidade desses modelos preditivos, observando seu custo computacional e não apenas sua precisão estatística.

Dicas da Máquina Virtual

Após o início da VM, clique no canto superior esquerdo para mudar para a aba Notebook para acessar o Jupyter Notebook para praticar.

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

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

Carregar o conjunto de dados

from sklearn.datasets import load_digits

X, y = load_digits(return_X_y=True)

Definir os modelos

from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC

naive_bayes = GaussianNB()
svc = SVC(kernel="rbf", gamma=0.001)

Plotar as curvas de aprendizagem

import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import LearningCurveDisplay, ShuffleSplit

fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 6), sharey=True)

common_params = {
    "X": X,
    "y": y,
    "train_sizes": np.linspace(0.1, 1.0, 5),
    "cv": ShuffleSplit(n_splits=50, test_size=0.2, random_state=0),
    "score_type": "both",
    "n_jobs": 4,
    "line_kw": {"marker": "o"},
    "std_display_style": "fill_between",
    "score_name": "Precisão",
}

for ax_idx, estimator in enumerate([naive_bayes, svc]):
    LearningCurveDisplay.from_estimator(estimator, **common_params, ax=ax[ax_idx])
    handles, label = ax[ax_idx].get_legend_handles_labels()
    ax[ax_idx].legend(handles[:2], ["Pontuação de Treinamento", "Pontuação de Teste"])
    ax[ax_idx].set_title(f"Curva de Aprendizagem para {estimator.__class__.__name__}")

Analisar as curvas de aprendizagem

## Interpretar as curvas de aprendizagem

Podemos analisar a curva de aprendizagem do classificador Naive Bayes. Sua forma pode ser encontrada frequentemente em conjuntos de dados mais complexos: a pontuação de treinamento é muito alta ao usar poucas amostras para treinamento e diminui ao aumentar o número de amostras, enquanto a pontuação de teste é muito baixa no início e depois aumenta ao adicionar amostras. As pontuações de treinamento e teste tornam-se mais realistas quando todas as amostras são usadas para treinamento.

Observamos outra curva de aprendizagem típica para o classificador SVM com kernel RBF. A pontuação de treinamento permanece alta, independentemente do tamanho do conjunto de treinamento. Por outro lado, a pontuação de teste aumenta com o tamanho do conjunto de dados de treinamento. De fato, ela aumenta até um ponto em que atinge um platô. Observar tal platô é uma indicação de que pode não ser útil adquirir novos dados para treinar o modelo, pois o desempenho de generalização do modelo não aumentará mais.

Verificar a escalabilidade dos modelos

from sklearn.model_selection import learning_curve

common_params = {
    "X": X,
    "y": y,
    "train_sizes": np.linspace(0.1, 1.0, 5),
    "cv": ShuffleSplit(n_splits=50, test_size=0.2, random_state=0),
    "n_jobs": 4,
    "return_times": True,
}

train_sizes, _, test_scores_nb, fit_times_nb, score_times_nb = learning_curve(
    naive_bayes, **common_params
)
train_sizes, _, test_scores_svm, fit_times_svm, score_times_svm = learning_curve(
    svc, **common_params
)

Plotar a escalabilidade dos modelos

fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(16, 12), sharex=True)

for ax_idx, (fit_times, score_times, estimator) in enumerate(
    zip(
        [fit_times_nb, fit_times_svm],
        [score_times_nb, score_times_svm],
        [naive_bayes, svc],
    )
):
    ## escalabilidade em relação ao tempo de ajuste
    ax[0, ax_idx].plot(train_sizes, fit_times.mean(axis=1), "o-")
    ax[0, ax_idx].fill_between(
        train_sizes,
        fit_times.mean(axis=1) - fit_times.std(axis=1),
        fit_times.mean(axis=1) + fit_times.std(axis=1),
        alpha=0.3,
    )
    ax[0, ax_idx].set_ylabel("Tempo de ajuste (s)")
    ax[0, ax_idx].set_title(
        f"Escalabilidade do classificador {estimator.__class__.__name__}"
    )

    ## escalabilidade em relação ao tempo de pontuação
    ax[1, ax_idx].plot(train_sizes, score_times.mean(axis=1), "o-")
    ax[1, ax_idx].fill_between(
        train_sizes,
        score_times.mean(axis=1) - score_times.std(axis=1),
        score_times.mean(axis=1) + score_times.std(axis=1),
        alpha=0.3,
    )
    ax[1, ax_idx].set_ylabel("Tempo de pontuação (s)")
    ax[1, ax_idx].set_xlabel("Número de amostras de treinamento")

Verificar o trade-off entre tempo de treinamento aumentado e pontuação de validação cruzada

fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(16, 6))

for ax_idx, (fit_times, test_scores, estimator) in enumerate(
    zip(
        [fit_times_nb, fit_times_svm],
        [test_scores_nb, test_scores_svm],
        [naive_bayes, svc],
    )
):
    ax[ax_idx].plot(fit_times.mean(axis=1), test_scores.mean(axis=1), "o-")
    ax[ax_idx].fill_between(
        fit_times.mean(axis=1),
        test_scores.mean(axis=1) - test_scores.std(axis=1),
        test_scores.mean(axis=1) + test_scores.std(axis=1),
        alpha=0.3,
    )
    ax[ax_idx].set_ylabel("Precisão")
    ax[ax_idx].set_xlabel("Tempo de ajuste (s)")
    ax[ax_idx].set_title(
        f"Desempenho do classificador {estimator.__class__.__name__}"
    )

plt.show()

Resumo

Neste laboratório, demonstramos como utilizar a classe LearningCurveDisplay do scikit-learn para plotar curvas de aprendizado. Analisamos a curva de aprendizado de um classificador Naive Bayes e um classificador SVM com kernel RBF utilizando o conjunto de dados de dígitos. Além disso, examinamos a escalabilidade desses modelos preditivos, analisando seu custo computacional e não apenas sua precisão estatística. Observamos que a escalabilidade dos classificadores SVM e Naive Bayes é muito diferente. A complexidade do classificador SVM no tempo de ajuste e pontuação aumenta rapidamente com o número de amostras. Em contraste, o classificador Naive Bayes escala muito melhor, com menor complexidade no tempo de ajuste e pontuação. Também verificamos o trade-off entre o aumento do tempo de treinamento e a pontuação de validação cruzada.