Comparar Métodos de Decomposição Cruzada

Beginner

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

Introdução

Neste laboratório, aprenderemos a utilizar diferentes algoritmos de decomposição cruzada, como PLS Canônico, Regressão PLS e CCA, para extrair direções de covariância de conjuntos de dados multivariados.

Dicas da Máquina Virtual

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

Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar o carregamento. 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 o problema rapidamente para si.

Criação de Conjuntos de Dados

Criamos um conjunto de dados com dois conjuntos de dados bivariados covariantes, X e Y. Em seguida, extraímos as direções de covariância, ou seja, os componentes de cada conjunto de dados que explicam a maior variância partilhada entre ambos os conjuntos de dados.

import numpy as np

n = 500
## 2 variáveis latentes:
l1 = np.random.normal(size=n)
l2 = np.random.normal(size=n)

latents = np.array([l1, l1, l2, l2]).T
X = latents + np.random.normal(size=4 * n).reshape((n, 4))
Y = latents + np.random.normal(size=4 * n).reshape((n, 4))

X_train = X[: n // 2]
Y_train = Y[: n // 2]
X_test = X[n // 2 :]
Y_test = Y[n // 2 :]

print("Corr(X)")
print(np.round(np.corrcoef(X.T), 2))
print("Corr(Y)")
print(np.round(np.corrcoef(Y.T), 2))

PLS Canônico

Utilizamos o algoritmo PLS Canônico para transformar os dados. Em seguida, criamos um gráfico de dispersão das pontuações.

from sklearn.cross_decomposition import PLSCanonical

plsca = PLSCanonical(n_components=2)
plsca.fit(X_train, Y_train)
X_train_r, Y_train_r = plsca.transform(X_train, Y_train)
X_test_r, Y_test_r = plsca.transform(X_test, Y_test)

import matplotlib.pyplot as plt

## No gráfico diagonal, plotamos as pontuações de X vs Y em cada componente
plt.figure(figsize=(12, 8))
plt.subplot(221)
plt.scatter(X_train_r[:, 0], Y_train_r[:, 0], label="treino", marker="o", s=25)
plt.scatter(X_test_r[:, 0], Y_test_r[:, 0], label="teste", marker="o", s=25)
plt.xlabel("Pontuações x")
plt.ylabel("Pontuações y")
plt.title(
    "Comp. 1: X vs Y (corr. teste = %.2f)"
    % np.corrcoef(X_test_r[:, 0], Y_test_r[:, 0])[0, 1]
)
plt.xticks(())
plt.yticks(())
plt.legend(loc="best")

plt.subplot(224)
plt.scatter(X_train_r[:, 1], Y_train_r[:, 1], label="treino", marker="o", s=25)
plt.scatter(X_test_r[:, 1], Y_test_r[:, 1], label="teste", marker="o", s=25)
plt.xlabel("Pontuações x")
plt.ylabel("Pontuações y")
plt.title(
    "Comp. 2: X vs Y (corr. teste = %.2f)"
    % np.corrcoef(X_test_r[:, 1], Y_test_r[:, 1])[0, 1]
)
plt.xticks(())
plt.yticks(())
plt.legend(loc="best")

## Gráfico fora da diagonal, plotando os componentes 1 vs 2 para X e Y
plt.subplot(222)
plt.scatter(X_train_r[:, 0], X_train_r[:, 1], label="treino", marker="*", s=50)
plt.scatter(X_test_r[:, 0], X_test_r[:, 1], label="teste", marker="*", s=50)
plt.xlabel("Comp. 1 de X")
plt.ylabel("Comp. 2 de X")
plt.title(
    "Comp. 1 de X vs Comp. 2 de X (corr. teste = %.2f)"
    % np.corrcoef(X_test_r[:, 0], X_test_r[:, 1])[0, 1]
)
plt.legend(loc="best")
plt.xticks(())
plt.yticks(())

plt.subplot(223)
plt.scatter(Y_train_r[:, 0], Y_train_r[:, 1], label="treino", marker="*", s=50)
plt.scatter(Y_test_r[:, 0], Y_test_r[:, 1], label="teste", marker="*", s=50)
plt.xlabel("Comp. 1 de Y")
plt.ylabel("Comp. 2 de Y")
plt.title(
    "Comp. 1 de Y vs Comp. 2 de Y, (corr. teste = %.2f)"
    % np.corrcoef(Y_test_r[:, 0], Y_test_r[:, 1])[0, 1]
)
plt.legend(loc="best")
plt.xticks(())
plt.yticks(())
plt.show()

Regressão PLS com Resposta Multivariada (PLS2)

Utilizamos o algoritmo de Regressão PLS com resposta multivariada para estimar os valores de uma matriz B. Em seguida, comparamos a B estimada com a B verdadeira.

n = 1000
q = 3
p = 10
X = np.random.normal(size=n * p).reshape((n, p))
B = np.array([[1, 2] + [0] * (p - 2)] * q).T
## cada Yj = 1*X1 + 2*X2 + ruído
Y = np.dot(X, B) + np.random.normal(size=n * q).reshape((n, q)) + 5

from sklearn.cross_decomposition import PLSRegression

pls2 = PLSRegression(n_components=3)
pls2.fit(X, Y)
print("B Verdadeiro (tal que: Y = XB + Erro)")
print(B)
## comparar pls2.coef_ com B
print("B Estimado")
print(np.round(pls2.coef_, 1))
pls2.predict(X)

Regressão PLS com Resposta Univariada (PLS1)

Utilizamos o algoritmo de Regressão PLS com resposta univariada para estimar os valores de beta.

n = 1000
p = 10
X = np.random.normal(size=n * p).reshape((n, p))
y = X[:, 0] + 2 * X[:, 1] + np.random.normal(size=n * 1) + 5
pls1 = PLSRegression(n_components=3)
pls1.fit(X, y)
## observe que o número de componentes excede 1 (a dimensão de y)
print("Betas estimados")
print(np.round(pls1.coef_, 1))

CCA (modo PLS B com deflação simétrica)

Utilizamos o algoritmo CCA para transformar os dados.

cca = CCA(n_components=2)
cca.fit(X_train, Y_train)
X_train_r, Y_train_r = cca.transform(X_train, Y_train)
X_test_r, Y_test_r = cca.transform(X_test, Y_test)

Sumário

Neste laboratório, aprendemos a utilizar diferentes algoritmos de decomposição cruzada para extrair direções de covariância de conjuntos de dados multivariados. Criamos um conjunto de dados, transformamos os dados usando PLS Canônico, Regressão PLS e CCA, e estimamos os valores de matrizes e betas. Também criamos gráficos de dispersão para visualizar as pontuações dos componentes.