gpt4 book ai didi

python-2.7 - 使用 sklearn 进行 PCA 逆变换(白色=True)

转载 作者:行者123 更新时间:2023-12-02 11:28:36 25 4
gpt4 key购买 nike

通常 PCA 变换很容易反转:

import numpy as np
from sklearn import decomposition

x = np.zeros((500, 10))
x[:, :5] = random.rand(500, 5)
x[:, 5:] = x[:, :5] # so that using PCA would make sense

p = decomposition.PCA()
p.fit(x)

a = x[5, :]

print p.inverse_transform(p.transform(a)) - a # this yields small numbers (about 10**-16)

现在,如果我们尝试添加whiten=True参数,结果将完全不同:

p = decomposition.PCA(whiten=True)
p.fit(x)

a = x[5, :]

print p.inverse_transform(p.transform(a)) - a # now yields numbers about 10**15

所以,由于我没有找到任何其他方法可以做到这一点,我想知道如何才能获得 a 的原始值?或者说这根本有可能吗?非常感谢您的帮助。

最佳答案

这种行为确实可能很奇怪,但它仍然记录在相关函数的文档字符串中。

PCA 的类文档字符串对 whiten 进行了如下描述:

whiten : bool, optional
When True (False by default) the `components_` vectors are divided
by n_samples times singular values to ensure uncorrelated outputs
with unit component-wise variances.

Whitening will remove some information from the transformed signal
(the relative variance scales of the components) but can sometime
improve the predictive accuracy of the downstream estimators by
making there data respect some hard-wired assumptions.

PCA.inverse_transform 的代码和文档字符串说:

def inverse_transform(self, X):
"""Transform data back to its original space, i.e.,
return an input X_original whose transform would be X

Parameters
----------
X : array-like, shape (n_samples, n_components)
New data, where n_samples is the number of samples
and n_components is the number of components.

Returns
-------
X_original array-like, shape (n_samples, n_features)

Notes
-----
If whitening is enabled, inverse_transform does not compute the
exact inverse operation as transform.
"""
return np.dot(X, self.components_) + self.mean_

现在看看函数 PCA._fitwhiten=True 时会发生什么:

    if self.whiten:
self.components_ = V / S[:, np.newaxis] * np.sqrt(n_samples)
else:
self.components_ = V

其中 S 是奇异值,V 是奇异向量。根据定义,白化对频谱进行分级,本质上是将协方差矩阵的所有特征值设置为 1

为了最终回答你的问题:sklearn.decomposition的PCA对象不允许从白化矩阵重建原始数据,因为奇异值中心数据/协方差矩阵的特征值在函数PCA._fit之后被垃圾收集。

但是,如果您手动获取奇异值S,您将能够将它们相乘并返回原始数据。

试试这个

import numpy as np
rng = np.random.RandomState(42)

n_samples_train, n_features = 40, 10
n_samples_test = 20
X_train = rng.randn(n_samples_train, n_features)
X_test = rng.randn(n_samples_test, n_features)

from sklearn.decomposition import PCA
pca = PCA(whiten=True)

pca.fit(X_train)

X_train_mean = X_train.mean(0)
X_train_centered = X_train - X_train_mean
U, S, VT = np.linalg.svd(X_train_centered, full_matrices=False)
components = VT / S[:, np.newaxis] * np.sqrt(n_samples_train)

from numpy.testing import assert_array_almost_equal
# These assertions will raise an error if the arrays aren't equal
assert_array_almost_equal(components, pca.components_) # we have successfully
# calculated whitened components

transformed = pca.transform(X_test)
inverse_transformed = transformed.dot(S[:, np.newaxis] ** 2 * pca.components_ /
n_samples_train) + X_train_mean

assert_array_almost_equal(inverse_transformed, X_test) # We have equality

从创建inverse_transformed的行可以看出,如果将奇异值乘回到分量,就可以返回到原始空间。

事实上,奇异值S实际上隐藏在分量的范数中,因此不需要沿着PCA计算SVD 。使用上面的定义可以看到

S_recalculated = 1. / np.sqrt((pca.components_ ** 2).sum(axis=1) / n_samples_train)
assert_array_almost_equal(S, S_recalculated)

结论:通过获得中心数据矩阵的奇异值,我们能够撤销白化并变换回原始空间。但是,此功能并未在 PCA 对象中原生实现。

补救措施:在不修改 scikit learn 代码的情况下(如果社区认为有用,可以正式完成),您正在寻找的解决方案是这样的(并且我现在将使用您的代码和变量名称,请检查这是否适合您):

transformed_a = p.transform(a)
singular_values = 1. / np.sqrt((p.components_ ** 2).sum(axis=1) / len(x))
inverse_transformed = np.dot(transformed_a, singular_values[:, np.newaxis] ** 2 *
p.components_ / len(x)) + p.mean_)

(恕我直言,任何估计器的 inverse_transform 函数都应该尽可能返回到原始数据。在这种情况下,显式存储奇异值也不会花费太多,所以也许这个功能实际上应该添加到 sklearn 中。)

编辑 中心矩阵的奇异值并不像最初想象的那样被垃圾收集。事实上,它们存储在 pca.explained_variance_ 中,可以用来反白化。查看评论。

关于python-2.7 - 使用 sklearn 进行 PCA 逆变换(白色=True),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23254700/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com