Spec-Zone.ru › scikit-learn

Примечание

Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере с помощью JupyterLite или Binder.

Регрессия главных компонент и регрессия частных наименьших квадратов

В этом примере сравниваются регрессия главных компонент (PCR) и регрессия частных наименьших квадратов (PLS) на игрушечном наборе данных. Наша цель — показать, как PLS может превзойти PCR, когда целевая переменная сильно коррелирует с некоторыми направлениями данных, имеющими низкую дисперсию.

PCR — это регрессор, состоящий из двух этапов: сначала к обучающим данным применяется PCA, возможно, с уменьшением размерности; затем на преобразованных образцах обучается регрессор (например, линейный регрессор). В PCA преобразование является полностью неконтролируемым, то есть информация о целевых переменных не используется. В результате PCR может плохо работать на некоторых наборах данных, где целевая переменная сильно коррелирует с направлениями, имеющими низкую дисперсию. Действительно, уменьшение размерности с помощью PCA проецирует данные в пространство меньшей размерности, в котором дисперсия проецируемых данных жадно максимизируется вдоль каждой оси. Несмотря на то что направления с меньшей дисперсией обладают наибольшей предсказательной способностью для целевой переменной, они будут отброшены, и итоговый регрессор не сможет их использовать.

PLS — это одновременно преобразователь и регрессор, и он очень похож на PCR: он также уменьшает размерность образцов перед применением линейного регрессора к преобразованным данным. Основное отличие от PCR заключается в том, что преобразование PLS является контролируемым. Поэтому, как мы увидим в этом примере, оно не страдает от описанной выше проблемы.

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

Данные

Сначала создадим простой набор данных с двумя признаками. Прежде чем перейти к PCR и PLS, обучим оцениватель PCA, чтобы показать две главные компоненты этого набора данных, то есть два направления, объясняющие наибольшую дисперсию данных.

import matplotlib.pyplot as plt
import numpy as np

from sklearn.decomposition import PCA

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)
pca = PCA(n_components=2).fit(X)


plt.scatter(X[:, 0], X[:, 1], alpha=0.3, label="samples")
for i, (comp, var) in enumerate(zip(pca.components_, pca.explained_variance_)):
    comp = comp * var  # scale component by its variance explanation power
    plt.plot(
        [0, comp[0]],
        [0, comp[1]],
        label=f"Component {i}",
        linewidth=5,
        color=f"C{i + 2}",
    )
plt.gca().set(
    aspect="equal",
    title="2-dimensional dataset with principal components",
    xlabel="first feature",
    ylabel="second feature",
)
plt.legend()
plt.show()
2-dimensional dataset with principal components

Для целей этого примера теперь определим целевую переменную 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="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()
plot pcr vs pls

Проекция на одну компоненту и предсказательная способность

Теперь создадим два регрессора: PCR и PLS. Для наглядности установим число компонент равным 1. Перед подачей данных на этап PCA в PCR сначала стандартизируем их, как рекомендуют правила хорошей практики. Оцениватель PLS обладает встроенными возможностями масштабирования.

Для обеих моделей построим график зависимости целевой переменной от данных, спроецированных на первую компоненту. В обоих случаях эти проецированные данные будут использоваться регрессорами в качестве обучающих данных.

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

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)

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()
PCR / PCA, PLS

Как и ожидалось, неконтролируемое преобразование PCA в PCR отбросило вторую компоненту, то есть направление с наименьшей дисперсией, несмотря на то что оно является наиболее предсказательным. Это происходит потому, что PCA — полностью неконтролируемое преобразование, в результате которого проецируемые данные обладают низкой предсказательной способностью относительно целевой переменной.

С другой стороны, регрессору PLS удаётся уловить влияние направления с наименьшей дисперсией благодаря использованию информации о целевой переменной при преобразовании: он может определить, что это направление на самом деле является наиболее предсказательным. Отметим, что первая компонента PLS отрицательно коррелирует с целевой переменной. Это объясняется тем, что знаки собственных векторов произвольны.

Мы также выводим значения R-квадрата для обоих оценивателей, что дополнительно подтверждает: в данном случае PLS — лучшая альтернатива PCR. Отрицательное значение R-квадрата указывает на то, что 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}")
PCR r-squared -0.026
PLS r-squared 0.658

В заключение отметим, что PCR с двумя компонентами работает не хуже PLS: в этом случае 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 r-squared with 2 components 0.673

Общее время выполнения скрипта: (0 минут 0.483 секунды)

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_pcr_vs_pls.ipynb

Download Python source code: plot_pcr_vs_pls.py

Download zipped: plot_pcr_vs_pls.zip

Связанные примеры

Сравнение методов кросс-декомпозиции

Важность масштабирования признаков

Анализ главных компонент (PCA) на наборе данных Iris

Преобразование данных к нормальному распределению

© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/cross_decomposition/plot_pcr_vs_pls.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API