Comparação de Floresta Aleatória e Reforço de Gradiente Histograma

Beginner

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

Introdução

Neste laboratório, compararemos o desempenho de dois modelos de conjunto populares, Random Forest (RF) e Histogram Gradient Boosting (HGBT), para um conjunto de dados de regressão em termos de pontuação e tempo de computação. Variaremos os parâmetros que controlam o número de árvores de acordo com cada estimador e plotaremos os resultados para visualizar o trade-off entre o tempo de computação decorrido e a pontuação média de teste.

Dicas da Máquina Virtual

Após o arranque da VM, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para a prática.

Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar 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, não hesite em contactar o Labby. Forneça feedback após a sessão e resolveremos prontamente o problema para si.

Carregar Conjunto de Dados

Vamos carregar o conjunto de dados de habitação da Califórnia usando a função fetch_california_housing do scikit-learn. Este conjunto de dados consiste em 20.640 amostras e 8 características.

from sklearn.datasets import fetch_california_housing

X, y = fetch_california_housing(return_X_y=True, as_frame=True)
n_samples, n_features = X.shape

print(f"O conjunto de dados consiste em {n_samples} amostras e {n_features} características")

Definir Modelos e Malhas de Parâmetros

Vamos definir dois modelos, Random Forest e Histogram Gradient Boosting, com suas respectivas malhas de parâmetros usando as classes RandomForestRegressor, HistGradientBoostingRegressor e GridSearchCV do scikit-learn. Também definiremos o número de núcleos físicos da máquina hospedeira a usar para processamento paralelo.

import joblib
import pandas as pd
from sklearn.ensemble import HistGradientBoostingRegressor, RandomForestRegressor
from sklearn.model_selection import GridSearchCV, KFold

N_CORES = joblib.cpu_count(only_physical_cores=True)

models = {
    "Random Forest": RandomForestRegressor(
        min_samples_leaf=5, random_state=0, n_jobs=N_CORES
    ),
    "Hist Gradient Boosting": HistGradientBoostingRegressor(
        max_leaf_nodes=15, random_state=0, early_stopping=False
    ),
}

param_grids = {
    "Random Forest": {"n_estimators": [10, 20, 50, 100]},
    "Hist Gradient Boosting": {"max_iter": [10, 20, 50, 100, 300, 500]},
}

cv = KFold(n_splits=4, shuffle=True, random_state=0)

results = []

for name, model in models.items():
    grid_search = GridSearchCV(
        estimator=model,
        param_grid=param_grids[name],
        return_train_score=True,
        cv=cv,
    ).fit(X, y)

    result = {"model": name, "cv_results": pd.DataFrame(grid_search.cv_results_)}
    results.append(result)

Calcular Pontuações e Tempos de Computação

Vamos calcular os tempos médios de ajuste e pontuação para cada combinação de hiperparâmetros usando o atributo cv_results_ do objeto GridSearchCV. Em seguida, plotaremos os resultados usando plotly.express.scatter e plotly.express.line para visualizar o trade-off entre o tempo de computação decorrido e a pontuação média de teste.

import plotly.express as px
import plotly.colors as colors
from plotly.subplots import make_subplots

fig = make_subplots(
    rows=1,
    cols=2,
    shared_yaxes=True,
    subplot_titles=["Tempo de treinamento vs pontuação", "Tempo de predição vs pontuação"],
)
model_names = [result["model"] for result in results]
colors_list = colors.qualitative.Plotly * (
    len(model_names) // len(colors.qualitative.Plotly) + 1
)

for idx, result in enumerate(results):
    cv_results = result["cv_results"].round(3)
    model_name = result["model"]
    param_name = list(param_grids[model_name].keys())[0]
    cv_results[param_name] = cv_results["param_" + param_name]
    cv_results["model"] = model_name

    scatter_fig = px.scatter(
        cv_results,
        x="mean_fit_time",
        y="mean_test_score",
        error_x="std_fit_time",
        error_y="std_test_score",
        hover_data=param_name,
        color="model",
    )
    line_fig = px.line(
        cv_results,
        x="mean_fit_time",
        y="mean_test_score",
    )

    scatter_trace = scatter_fig["data"][0]
    line_trace = line_fig["data"][0]
    scatter_trace.update(marker=dict(color=colors_list[idx]))
    line_trace.update(line=dict(color=colors_list[idx]))
    fig.add_trace(scatter_trace, row=1, col=1)
    fig.add_trace(line_trace, row=1, col=1)

    scatter_fig = px.scatter(
        cv_results,
        x="mean_score_time",
        y="mean_test_score",
        error_x="std_score_time",
        error_y="std_test_score",
        hover_data=param_name,
    )
    line_fig = px.line(
        cv_results,
        x="mean_score_time",
        y="mean_test_score",
    )

    scatter_trace = scatter_fig["data"][0]
    line_trace = line_fig["data"][0]
    scatter_trace.update(marker=dict(color=colors_list[idx]))
    line_trace.update(line=dict(color=colors_list[idx]))
    fig.add_trace(scatter_trace, row=1, col=2)
    fig.add_trace(line_trace, row=1, col=2)

fig.update_layout(
    xaxis=dict(title="Tempo de treinamento (s) - menor é melhor"),
    yaxis=dict(title="Pontuação R2 de teste - maior é melhor"),
    xaxis2=dict(title="Tempo de predição (s) - menor é melhor"),
    legend=dict(x=0.72, y=0.05, traceorder="normal", borderwidth=1),
    title=dict(x=0.5, text="Trade-off entre velocidade e pontuação de conjuntos de árvores"),
)

Interpretar Resultados

Podemos observar que ambos os modelos HGBT e RF melhoram ao aumentar o número de árvores no conjunto. No entanto, as pontuações atingem um platô onde adicionar novas árvores apenas torna o ajuste e a pontuação mais lentos. O modelo RF atinge esse platô mais cedo e nunca consegue alcançar a pontuação de teste do modelo HGBDT maior. Os modelos HGBT dominam uniformemente os modelos RF no "trade-off entre pontuação de teste e velocidade de treinamento" e o "trade-off entre pontuação de teste e velocidade de predição" também pode ser mais favorável aos HGBT. O HGBT quase sempre oferece um trade-off velocidade-precisão mais favorável do que o RF, seja com os hiperparâmetros padrão ou incluindo o custo de ajuste de hiperparâmetros.

Resumo

Neste laboratório, comparamos o desempenho de dois modelos de conjunto populares, Floresta Aleatória e Reforço de Gradiente Histograma, para um conjunto de dados de regressão em termos de pontuação e tempo de computação. Variamos os parâmetros que controlam o número de árvores de acordo com cada estimador e plotamos os resultados para visualizar o trade-off entre o tempo de computação decorrido e a pontuação média de teste. Observamos que os modelos HGBT dominam uniformemente os modelos RF no "trade-off entre pontuação de teste e velocidade de treinamento" e o "trade-off entre pontuação de teste e velocidade de predição" também pode ser mais favorável aos HGBT. O HGBT quase sempre oferece um trade-off velocidade-precisão mais favorável do que o RF, seja com os hiperparâmetros padrão ou incluindo o custo de ajuste de hiperparâmetros.