PCR 대 PLS 플롯

Beginner

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

소개

주성분 회귀 (PCR) 와 부분 최소 제곱 회귀 (PLS) 는 회귀 분석에 사용되는 두 가지 방법입니다. PCR 은 훈련 데이터에 PCA 를 적용한 후 변환된 샘플에 회귀자를 훈련시키는 것을 포함합니다. PCA 변환은 비지도 학습이므로 대상에 대한 정보를 사용하지 않습니다. 결과적으로, 대상이 낮은 분산을 가진 방향과 강하게 상관되는 일부 데이터 세트에서 PCR 의 성능이 저하될 수 있습니다.

PLS 는 변환기이자 회귀자이며 PCR 과 매우 유사합니다. 변환된 데이터에 선형 회귀자를 적용하기 전에 샘플에 차원 축소를 적용하기도 합니다. PCR 과의 주요 차이점은 PLS 변환이 지도 학습이라는 것입니다. 따라서 위에서 언급한 문제가 발생하지 않습니다.

이 실험실에서는 소규모 데이터 세트에서 PCR 과 PLS 를 비교할 것입니다.

VM 팁

VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 Notebook 탭으로 전환하여 연습을 위한 Jupyter Notebook에 접근할 수 있습니다.

때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업의 유효성 검사를 자동화할 수 없습니다.

학습 중 문제가 발생하면 Labby 에게 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.

데이터셋 생성

두 개의 특징을 가진 간단한 데이터셋을 생성합니다. NumPy 라이브러리를 사용하여 데이터셋을 생성하고 Matplotlib 라이브러리를 사용하여 플롯합니다.

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="samples")
plt.gca().set(
    aspect="equal",
    title="주성분을 가진 2 차원 데이터셋",
    xlabel="첫 번째 특징",
    ylabel="두 번째 특징",
)
plt.legend()
plt.show()

대상 정의

이 예제의 목적상, 작은 분산을 가진 방향과 강하게 상관되는 대상 y를 정의합니다. X를 두 번째 성분에 투영하고 약간의 노이즈를 추가합니다.

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="첫 번째 주성분으로 투영된 데이터", ylabel="y")
axes[1].scatter(X.dot(pca.components_[1]), y, alpha=0.3)
axes[1].set(xlabel="두 번째 주성분으로 투영된 데이터", ylabel="y")
plt.tight_layout()
plt.show()

회귀자 생성

두 개의 회귀자 (PCR 및 PLS) 를 생성합니다. 이 예시에서는 구성 요소 수를 1 로 설정합니다. PCR 의 PCA 단계에 데이터를 입력하기 전에 권장되는 사례에 따라 데이터를 표준화합니다. PLS 추정기는 내장된 스케일링 기능을 가지고 있습니다.

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"]  ## retrieve the PCA step of the pipeline

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

회귀자 비교

PCR 및 PLS 회귀자 모두에 대해 첫 번째 구성 요소에 투영된 데이터를 대상과 함께 플롯합니다. 두 경우 모두 투영된 데이터가 회귀자가 학습 데이터로 사용할 데이터입니다.

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="첫 번째 주성분으로 투영된 데이터", 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="첫 번째 PLS 구성요소로 투영된 데이터", ylabel="y", title="PLS")
axes[1].legend()
plt.tight_layout()
plt.show()

두 추정기의 R-제곱 점수를 출력합니다. 이는 이 경우 PLS 가 PCR 보다 더 나은 대안임을 추가로 확인합니다.

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

2 개의 구성요소를 사용한 PCR

PLS 와 비교하기 위해 2 개의 구성요소를 사용한 PCR 을 사용합니다.

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

요약

이 실험에서 우리는 장난감 데이터 세트에서 PCR 과 PLS 를 비교했습니다. 대상이 분산이 낮은 방향과 강하게 상관 관계가 있을 때 PLS 가 PCR 보다 성능이 더 좋았습니다.