PCR と PLS の比較プロット

Beginner

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

はじめに

主成分回帰 (PCR) と偏最小二乗回帰 (PLS) は、回帰分析で使用される 2 つの方法です。PCR では、訓練データに PCA を適用した後、変換されたサンプルに対して回帰モデルを訓練します。PCA 変換は無監督学習であり、つまりターゲットに関する情報は使用されません。その結果、ターゲットが低分散の方向と強く相関している一部のデータセットでは、PCR の性能が低下する場合があります。

PLS は、変換器であり回帰モデルでもあり、PCR と非常に似ています。また、線形回帰モデルを適用する前に、サンプルに次元削減を適用します。PCR との主な違いは、PLS 変換が監督学習であることです。したがって、上記の問題には悩まされません。

この実験では、単純なデータセットで PCR と PLS を比較します。

VM のヒント

VM の起動が完了した後、左上隅をクリックして ノートブック タブに切り替え、Jupyter Notebook を使用して練習します。

場合によっては、Jupyter Notebook が読み込み完了するまで数秒待つ必要があります。Jupyter Notebook の制限により、操作の検証は自動化できません。

学習中に問題が発生した場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。

データセットの作成

まず、2 つの特徴量を持つ単純なデータセットを作成します。データセットの作成には 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-dimensional dataset with principal components",
    xlabel="first feature",
    ylabel="second feature",
)
plt.legend()
plt.show()

ターゲットの定義

この例の目的のために、ターゲット y を、分散の小さい方向と強く相関するように定義します。X を第 2 主成分に射影し、そこにノイズを加えます。

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="Projected data onto first PCA component", ylabel="y")
axes[1].scatter(X.dot(pca.components_[1]), y, alpha=0.3)
axes[1].set(xlabel="Projected data onto second PCA component", ylabel="y")
plt.tight_layout()
plt.show()

回帰モデルの作成

PCR と PLS の 2 つの回帰モデルを作成します。この例では、主成分数を 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 の両方の回帰モデルについて、第 1 主成分に射影したデータとターゲットをプロットします。どちらの場合も、この射影データが回帰モデルの訓練データとして使用されます。

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="Projected data onto first PCA component", 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="Projected data onto first PLS component", ylabel="y", title="PLS")
axes[1].legend()
plt.tight_layout()
plt.show()

両方の推定器の決定係数(R-squared)を表示します。これにより、このケースでは 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 よりも良好な性能を示すことがわかりました。