Gráfico PCR vs PLS

Beginner

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

Introdução

A Regressão de Componentes Principais (PCR) e a Regressão de Mínimos Quadrados Parciais (PLS) são dois métodos utilizados na análise de regressão. A PCR envolve a aplicação da PCA aos dados de treino, seguida do treino de um regressor nas amostras transformadas. A transformação PCA é não supervisionada, o que significa que nenhuma informação sobre as variáveis-alvo é utilizada. Como resultado, a PCR pode ter um desempenho fraco em alguns conjuntos de dados onde a variável-alvo está fortemente correlacionada com direções que têm baixa variância.

A PLS é simultaneamente um transformador e um regressor, e é bastante semelhante à PCR. Também aplica uma redução de dimensionalidade às amostras antes de aplicar um regressor linear aos dados transformados. A principal diferença em relação à PCR é que a transformação PLS é supervisionada. Portanto, não sofre do problema mencionado acima.

Neste laboratório, vamos comparar a PCR e a PLS num conjunto de dados de exemplo.

Dicas da Máquina Virtual

Após o arranque da máquina virtual, 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.

Criar um Conjunto de Dados

Começamos criando um conjunto de dados simples com duas características. Usamos a biblioteca numpy para criar o conjunto de dados e a biblioteca matplotlib para o representar graficamente.

import numpy as np
import matplotlib.pyplot as plt

rng = np.random.RandomState(0)
n_samples = 500
cov = [[3, 3], [3, 4]]
X = rng.multivariate_normal(mean=[0, 0], cov=cov, size=n_samples)
plt.scatter(X[:, 0], X[:, 1], alpha=0.3, label="amostras")
plt.gca().set(
    aspect="equal",
    title="Conjunto de dados bidimensional com componentes principais",
    xlabel="primeira característica",
    ylabel="segunda característica",
)
plt.legend()
plt.show()

Definir o Alvo

Para este exemplo, definimos o alvo y de forma que esteja fortemente correlacionado com uma direção que apresenta uma pequena variância. Projetamos X no segundo componente e adicionamos algum ruído a ele.

y = X.dot(pca.components_[1]) + rng.normal(size=n_samples) / 2

fig, axes = plt.subplots(1, 2, figsize=(10, 3))

axes[0].scatter(X.dot(pca.components_[0]), y, alpha=0.3)
axes[0].set(xlabel="Dados projetados no primeiro componente PCA", ylabel="y")
axes[1].scatter(X.dot(pca.components_[1]), y, alpha=0.3)
axes[1].set(xlabel="Dados projetados no segundo componente PCA", ylabel="y")
plt.tight_layout()
plt.show()

Criar os Regressores

Criamos dois regressores: PCR e PLS, e, para fins ilustrativos, definimos o número de componentes como 1. Antes de alimentar os dados para a etapa PCA do PCR, primeiro os padronizamos, conforme recomendado pelas boas práticas. O estimador PLS possui recursos de escalonamento embutidos.

from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.cross_decomposition import PLSRegression

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=rng)

pcr = make_pipeline(StandardScaler(), PCA(n_components=1), LinearRegression())
pcr.fit(X_train, y_train)
pca = pcr.named_steps["pca"]  ## recuperar a etapa PCA do pipeline

pls = PLSRegression(n_components=1)
pls.fit(X_train, y_train)

Comparar os Regressores

Plotamos os dados projetados no primeiro componente contra o alvo para os regressores PCR e PLS. Em ambos os casos, esses dados projetados são o que os regressores usarão como dados de treinamento.

fig, axes = plt.subplots(1, 2, figsize=(10, 3))
axes[0].scatter(pca.transform(X_test), y_test, alpha=0.3, label="ground truth")
axes[0].scatter(
    pca.transform(X_test), pcr.predict(X_test), alpha=0.3, label="predictions"
)
axes[0].set(
    xlabel="Dados projetados no primeiro componente PCA", ylabel="y", title="PCR / PCA"
)
axes[0].legend()
axes[1].scatter(pls.transform(X_test), y_test, alpha=0.3, label="ground truth")
axes[1].scatter(
    pls.transform(X_test), pls.predict(X_test), alpha=0.3, label="predictions"
)
axes[1].set(xlabel="Dados projetados no primeiro componente PLS", ylabel="y", title="PLS")
axes[1].legend()
plt.tight_layout()
plt.show()

Imprimimos as pontuações R-quadrado de ambos os estimadores, o que confirma ainda mais que o PLS é uma alternativa melhor que o PCR neste caso.

print(f"PCR r-squared {pcr.score(X_test, y_test):.3f}")
print(f"PLS r-squared {pls.score(X_test, y_test):.3f}")

Usar PCR com 2 Componentes

Usamos PCR com 2 componentes para compará-lo com PLS.

pca_2 = make_pipeline(PCA(n_components=2), LinearRegression())
pca_2.fit(X_train, y_train)
print(f"PCR r-squared com 2 componentes {pca_2.score(X_test, y_test):.3f}")

Resumo

Neste laboratório, comparamos PCR e PLS em um conjunto de dados de brinquedo. Descobrimos que o PLS teve um desempenho melhor que o PCR quando o alvo está fortemente correlacionado com direções que possuem baixa variância.