소개
이 실습에서는 PLS Canonical, PLS 회귀, CCA 와 같은 다양한 교차 분해 알고리즘을 사용하여 다변량 데이터 세트에서 공분산 방향을 추출하는 방법을 배웁니다.
VM 팁
VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 Notebook 탭으로 전환하여 연습을 위한 Jupyter Notebook에 접근합니다.
때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업의 유효성 검사는 자동화될 수 없습니다.
학습 중 문제가 발생하면 Labby 에게 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.
데이터셋 생성
두 개의 다변량 공분산 2 차원 데이터셋 X 와 Y 를 생성합니다. 그런 다음 두 데이터셋 간에 가장 많은 공유 분산을 설명하는 각 데이터셋의 성분, 즉 공분산 방향을 추출합니다.
import numpy as np
n = 500
## 2 개의 잠재 변수:
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 Canonical
PLS Canonical 알고리즘을 사용하여 데이터를 변환합니다. 그런 다음 점수의 산점도를 생성합니다.
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
## 대각선 플롯: 각 성분에서 X 와 Y 점수를 비교
plt.figure(figsize=(12, 8))
plt.subplot(221)
plt.scatter(X_train_r[:, 0], Y_train_r[:, 0], label="train", marker="o", s=25)
plt.scatter(X_test_r[:, 0], Y_test_r[:, 0], label="test", marker="o", s=25)
plt.xlabel("x 점수")
plt.ylabel("y 점수")
plt.title(
"성분 1: X 대 Y (테스트 상관 계수 = %.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="train", marker="o", s=25)
plt.scatter(X_test_r[:, 1], Y_test_r[:, 1], label="test", marker="o", s=25)
plt.xlabel("x 점수")
plt.ylabel("y 점수")
plt.title(
"성분 2: X 대 Y (테스트 상관 계수 = %.2f)"
% np.corrcoef(X_test_r[:, 1], Y_test_r[:, 1])[0, 1]
)
plt.xticks(())
plt.yticks(())
plt.legend(loc="best")
## 비대각선 플롯: X 와 Y 의 성분 1 대 성분 2
plt.subplot(222)
plt.scatter(X_train_r[:, 0], X_train_r[:, 1], label="train", marker="*", s=50)
plt.scatter(X_test_r[:, 0], X_test_r[:, 1], label="test", marker="*", s=50)
plt.xlabel("X 성분 1")
plt.ylabel("X 성분 2")
plt.title(
"X 성분 1 대 X 성분 2 (테스트 상관 계수 = %.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="train", marker="*", s=50)
plt.scatter(Y_test_r[:, 0], Y_test_r[:, 1], label="test", marker="*", s=50)
plt.xlabel("Y 성분 1")
plt.ylabel("Y 성분 2")
plt.title(
"Y 성분 1 대 Y 성분 2 (테스트 상관 계수 = %.2f)"
% np.corrcoef(Y_test_r[:, 0], Y_test_r[:, 1])[0, 1]
)
plt.legend(loc="best")
plt.xticks(())
plt.yticks(())
plt.show()
다변량 반응 변수를 갖는 PLS 회귀 (PLS2)
다변량 반응 변수를 갖는 PLS 회귀 알고리즘을 사용하여 행렬 B 의 값을 추정합니다. 그런 다음 추정된 B 와 실제 B 를 비교합니다.
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
## 각 Yj = 1*X1 + 2*X2 + 노이즈
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 (Y = XB + 오차)")
print(B)
## pls2.coef_와 B 를 비교
print("추정된 B")
print(np.round(pls2.coef_, 1))
pls2.predict(X)
단변량 반응 변수를 갖는 PLS 회귀 (PLS1)
단변량 반응 변수를 갖는 PLS 회귀 알고리즘을 사용하여 베타 값을 추정합니다.
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)
## y 의 차원 (1) 보다 성분의 수가 많음에 유의
print("추정된 베타 값")
print(np.round(pls1.coef_, 1))
CCA (대칭적 팽창을 갖는 PLS 모드 B)
데이터를 변환하기 위해 CCA 알고리즘을 사용합니다.
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)
요약
이 실험에서 다변량 데이터셋에서 공분산 방향을 추출하기 위해 서로 다른 교차 분해 알고리즘을 사용하는 방법을 배웠습니다. 데이터셋을 생성하고, PLS 표준형, PLS 회귀 및 CCA 를 사용하여 데이터를 변환하고, 행렬과 베타 값을 추정했습니다. 또한 성분의 점수를 시각화하기 위해 산점도를 생성했습니다.