比较交叉分解方法

Machine LearningMachine LearningBeginner
立即练习

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

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,我们将学习如何使用不同的交叉分解算法,如偏最小二乘典型相关分析(PLS Canonical)、偏最小二乘回归(PLS Regression)和典型相关分析(CCA),从多变量数据集中提取协方差方向。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到“笔记本”标签,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们会及时为你解决问题。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sklearn(("Sklearn")) -.-> sklearn/ModelSelectionandEvaluationGroup(["Model Selection and Evaluation"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn/ModelSelectionandEvaluationGroup -.-> sklearn/cross_decomposition("Cross decomposition") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/cross_decomposition -.-> lab-49089{{"比较交叉分解方法"}} ml/sklearn -.-> lab-49089{{"比较交叉分解方法"}} end

创建数据集

我们创建了一个包含两个多变量协变二维数据集 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)算法对数据进行变换。然后,我们创建得分的散点图。

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="最佳位置")

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="最佳位置")

## 在非对角线上绘制 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="最佳位置")
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="最佳位置")
plt.xticks(())
plt.yticks(())
plt.show()

具有多元响应的偏最小二乘回归(PLS2)

我们使用具有多元响应的偏最小二乘回归(PLS Regression)算法来估计矩阵 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)

具有单变量响应的偏最小二乘回归(PLS1)

我们使用具有单变量响应的偏最小二乘回归(PLS Regression)算法来估计β的值。

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)
## 注意,成分数量超过了 1(y 的维度)
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 Canonical)、偏最小二乘回归(PLS Regression)和典型相关分析(CCA)对数据进行变换,并估计了矩阵和β的值。我们还创建了散点图来可视化成分的得分。