Escalonamento de Recursos em Aprendizado de Máquina

Beginner

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

Introdução

A normalização de recursos é uma etapa de pré-processamento importante para muitos algoritmos de aprendizado de máquina. Envolve a redimensionamento de cada recurso de forma que tenha um desvio padrão de 1 e uma média de 0. Neste laboratório, exploraremos a importância da normalização de recursos e seu efeito em modelos de aprendizado de máquina usando a biblioteca scikit-learn em Python.

Dicas da Máquina Virtual

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

Às vezes, pode ser necessário aguardar 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 prontamente o problema para você.

Carregar e Preparar Dados

Vamos carregar o conjunto de dados de vinho do scikit-learn e dividi-lo em conjuntos de treinamento e teste. Também vamos escalar os recursos no conjunto de treinamento usando o StandardScaler do módulo de pré-processamento do scikit-learn.

from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

X, y = load_wine(return_X_y=True, as_frame=True)
scaler = StandardScaler().set_output(transform="pandas")

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.30, random_state=42
)
scaled_X_train = scaler.fit_transform(X_train)

Efeito da Rescala em um Modelo k-vizinhos

Usaremos um subconjunto de dois recursos do conjunto de dados de vinho para treinar um classificador K-vizinhos mais próximos. Visualizaremos o limite de decisão do classificador usando dados não escalonados e escalonados.

import matplotlib.pyplot as plt
from sklearn.inspection import DecisionBoundaryDisplay
from sklearn.neighbors import KNeighborsClassifier

X_plot = X[["proline", "hue"]]
X_plot_scaled = scaler.fit_transform(X_plot)
clf = KNeighborsClassifier(n_neighbors=20)

def fit_and_plot_model(X_plot, y, clf, ax):
    clf.fit(X_plot, y)
    disp = DecisionBoundaryDisplay.from_estimator(
        clf,
        X_plot,
        response_method="predict",
        alpha=0.5,
        ax=ax,
    )
    disp.ax_.scatter(X_plot["proline"], X_plot["hue"], c=y, s=20, edgecolor="k")
    disp.ax_.set_xlim((X_plot["proline"].min(), X_plot["proline"].max()))
    disp.ax_.set_ylim((X_plot["hue"].min(), X_plot["hue"].max()))
    return disp.ax_

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 6))

fit_and_plot_model(X_plot, y, clf, ax1)
ax1.set_title("KNN sem escala")

fit_and_plot_model(X_plot_scaled, y, clf, ax2)
ax2.set_xlabel("prolina escalonada")
ax2.set_ylabel("tom escalonado")
_ = ax2.set_title("KNN com escala")

Efeito da Rescala na Redução de Dimensionalidade com PCA

Usaremos a Análise de Componentes Principais (PCA) para reduzir a dimensionalidade do conjunto de dados de vinho. Compararemos os componentes principais encontrados usando PCA em dados não escalonados com aqueles obtidos ao usar um StandardScaler para escalar os dados primeiro.

import pandas as pd
from sklearn.decomposition import PCA

pca = PCA(n_components=2).fit(X_train)
scaled_pca = PCA(n_components=2).fit(scaled_X_train)
X_train_transformed = pca.transform(X_train)
X_train_std_transformed = scaled_pca.transform(scaled_X_train)

first_pca_component = pd.DataFrame(
    pca.components_[0], index=X.columns, columns=["without scaling"]
)
first_pca_component["with scaling"] = scaled_pca.components_[0]
first_pca_component.plot.bar(
    title="Pesos do primeiro componente principal", figsize=(6, 8)
)

_ = plt.tight_layout()

fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))

target_classes = range(0, 3)
colors = ("blue", "red", "green")
markers = ("^", "s", "o")

for target_class, color, marker in zip(target_classes, colors, markers):
    ax1.scatter(
        x=X_train_transformed[y_train == target_class, 0],
        y=X_train_transformed[y_train == target_class, 1],
        color=color,
        label=f"classe {target_class}",
        alpha=0.5,
        marker=marker,
    )

    ax2.scatter(
        x=X_train_std_transformed[y_train == target_class, 0],
        y=X_train_std_transformed[y_train == target_class, 1],
        color=color,
        label=f"classe {target_class}",
        alpha=0.5,
        marker=marker,
    )

ax1.set_title("Conjunto de dados de treinamento não escalonado após PCA")
ax2.set_title("Conjunto de dados de treinamento padronizado após PCA")

for ax in (ax1, ax2):
    ax.set_xlabel("1º componente principal")
    ax.set_ylabel("2º componente principal")
    ax.legend(loc="upper right")
    ax.grid()

_ = plt.tight_layout()

Efeito da Rescala no Desempenho do Modelo

Treinaremos um modelo de regressão logística com dados reduzidos por PCA para avaliar o efeito da escala de recursos no desempenho do modelo. Compararemos o desempenho do modelo com recursos não escalonados e escalonados.

import numpy as np
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LogisticRegressionCV
from sklearn.metrics import accuracy_score
from sklearn.metrics import log_loss

Cs = np.logspace(-5, 5, 20)

unscaled_clf = make_pipeline(pca, LogisticRegressionCV(Cs=Cs))
unscaled_clf.fit(X_train, y_train)

scaled_clf = make_pipeline(scaler, pca, LogisticRegressionCV(Cs=Cs))
scaled_clf.fit(X_train, y_train)

y_pred = unscaled_clf.predict(X_test)
y_pred_scaled = scaled_clf.predict(X_test)
y_proba = unscaled_clf.predict_proba(X_test)
y_proba_scaled = scaled_clf.predict_proba(X_test)

print("Precisão de teste para PCA não escalonado")
print(f"{accuracy_score(y_test, y_pred):.2%}\n")
print("Precisão de teste para dados padronizados com PCA")
print(f"{accuracy_score(y_test, y_pred_scaled):.2%}\n")
print("Log-loss para PCA não escalonado")
print(f"{log_loss(y_test, y_proba):.3}\n")
print("Log-loss para dados padronizados com PCA")
print(f"{log_loss(y_test, y_proba_scaled):.3}")

Resumo

Neste laboratório, aprendemos sobre a importância da escala de recursos em aprendizado de máquina e seu efeito no desempenho do modelo. Exploramos o efeito da escala de recursos em um modelo de vizinhos mais próximos (K-NN) e na redução de dimensionalidade por PCA. Também treinamos um modelo de regressão logística com dados reduzidos por PCA para avaliar o efeito da escala de recursos no desempenho do modelo. Descobrimos que escalar os recursos antes de reduzir a dimensionalidade resulta em componentes com a mesma ordem de grandeza e melhora a separabilidade das classes, levando a um melhor desempenho do modelo.