有没有办法在测试集上计算 PCA 的解释方差?
Is there a way to compute the explained variance of PCA on a test set?
我想看看 PCA 对我的数据的处理效果如何。
我在训练集上应用 PCA,并使用返回的 pca 对象在测试集上进行转换。 pca 对象有一个变量 pca.explained_variance_ratio_
,它告诉我训练集的每个选定组件解释的方差百分比。应用 pca 变换后,我想看看它在测试集上的效果如何。我尝试 inverse_transform()
返回原始值的样子,但我无法比较它在训练集和测试集上的工作方式。
pca = PCA(0.99)
pca.fit(train_df)
tranformed_test = pca.transform(test_df)
inverse_test = pca.inverse_transform(tranformed_test)
npt.assert_almost_equal(test_arr, inverse_test, decimal=2)
这个returns:
Arrays are not almost equal to 2 decimals
在transform()
之后有没有类似pca.explained_variance_ratio_
的东西?
每个组件的差异解释
您可以手动计算。
如果分量 X_i
是正交的(在 PCA 中就是这种情况),则 X_i
对 X
的解释方差是:1 - ||X_i - X||^2 / ||X - X_mean||^2
因此出现以下示例:
import numpy as np
from sklearn.decomposition import PCA
X_train = np.random.randn(200, 5)
X_test = np.random.randn(100, 5)
model = PCA(n_components=5).fit(X_train)
def explained_variance(X):
result = np.zeros(model.n_components)
for ii in range(model.n_components):
X_trans = model.transform(X)
X_trans_ii = np.zeros_like(X_trans)
X_trans_ii[:, ii] = X_trans[:, ii]
X_approx_ii = model.inverse_transform(X_trans_ii)
result[ii] = 1 - (np.linalg.norm(X_approx_ii - X) /
np.linalg.norm(X - model.mean_)) ** 2
return result
print(model.explained_variance_ratio_)
print(explained_variance(X_train))
print(explained_variance(X_test))
# [0.25335711 0.23100201 0.2195476 0.15717412 0.13891916]
# [0.25335711 0.23100201 0.2195476 0.15717412 0.13891916]
# [0.17851083 0.199134 0.24198887 0.23286815 0.14749816]
解释的总方差
或者,如果您只关心解释的总方差,您可以使用 r2_score
:
from sklearn.metrics import r2_score
model = PCA(n_components=2).fit(X_train)
print(model.explained_variance_ratio_.sum())
print(r2_score(X_train, model.inverse_transform(model.transform(X_train)),
multioutput='variance_weighted'))
print(r2_score(X_test, model.inverse_transform(model.transform(X_test)),
multioutput='variance_weighted'))
# 0.46445451252373826
# 0.46445451252373815
# 0.4470229486590848
我想看看 PCA 对我的数据的处理效果如何。
我在训练集上应用 PCA,并使用返回的 pca 对象在测试集上进行转换。 pca 对象有一个变量 pca.explained_variance_ratio_
,它告诉我训练集的每个选定组件解释的方差百分比。应用 pca 变换后,我想看看它在测试集上的效果如何。我尝试 inverse_transform()
返回原始值的样子,但我无法比较它在训练集和测试集上的工作方式。
pca = PCA(0.99)
pca.fit(train_df)
tranformed_test = pca.transform(test_df)
inverse_test = pca.inverse_transform(tranformed_test)
npt.assert_almost_equal(test_arr, inverse_test, decimal=2)
这个returns:
Arrays are not almost equal to 2 decimals
在transform()
之后有没有类似pca.explained_variance_ratio_
的东西?
每个组件的差异解释
您可以手动计算。
如果分量 X_i
是正交的(在 PCA 中就是这种情况),则 X_i
对 X
的解释方差是:1 - ||X_i - X||^2 / ||X - X_mean||^2
因此出现以下示例:
import numpy as np
from sklearn.decomposition import PCA
X_train = np.random.randn(200, 5)
X_test = np.random.randn(100, 5)
model = PCA(n_components=5).fit(X_train)
def explained_variance(X):
result = np.zeros(model.n_components)
for ii in range(model.n_components):
X_trans = model.transform(X)
X_trans_ii = np.zeros_like(X_trans)
X_trans_ii[:, ii] = X_trans[:, ii]
X_approx_ii = model.inverse_transform(X_trans_ii)
result[ii] = 1 - (np.linalg.norm(X_approx_ii - X) /
np.linalg.norm(X - model.mean_)) ** 2
return result
print(model.explained_variance_ratio_)
print(explained_variance(X_train))
print(explained_variance(X_test))
# [0.25335711 0.23100201 0.2195476 0.15717412 0.13891916]
# [0.25335711 0.23100201 0.2195476 0.15717412 0.13891916]
# [0.17851083 0.199134 0.24198887 0.23286815 0.14749816]
解释的总方差
或者,如果您只关心解释的总方差,您可以使用 r2_score
:
from sklearn.metrics import r2_score
model = PCA(n_components=2).fit(X_train)
print(model.explained_variance_ratio_.sum())
print(r2_score(X_train, model.inverse_transform(model.transform(X_train)),
multioutput='variance_weighted'))
print(r2_score(X_test, model.inverse_transform(model.transform(X_test)),
multioutput='variance_weighted'))
# 0.46445451252373826
# 0.46445451252373815
# 0.4470229486590848