【问题标题】:How to whiten matrix in PCA如何在 PCA 中白化矩阵
【发布时间】:2011-09-28 07:43:16
【问题描述】:

我正在使用 Python,并且我已经使用 this tutorial 实现了 PCA。

一切都很好,我得到了协方差,我做了一个成功的变换,把它带到原始尺寸没有问题。

但是我该如何进行美白呢?我尝试将特征向量除以特征值:

S, V = numpy.linalg.eig(cov)
V = V / S[:, numpy.newaxis]

并使用 V 来转换数据,但这会导致奇怪的数据值。 有人可以解释一下吗?

【问题讨论】:

  • 您可能想尝试更具体的数学场所,也许是与 numpy 或 scikits 相关的邮件列表。

标签: python pca scikits


【解决方案1】:

这是我从here 获得的一些用于矩阵白化的 Matlab 代码的 numpy 实现。

import numpy as np

def whiten(X,fudge=1E-18):

   # the matrix X should be observations-by-components

   # get the covariance matrix
   Xcov = np.dot(X.T,X)

   # eigenvalue decomposition of the covariance matrix
   d, V = np.linalg.eigh(Xcov)

   # a fudge factor can be used so that eigenvectors associated with
   # small eigenvalues do not get overamplified.
   D = np.diag(1. / np.sqrt(d+fudge))

   # whitening matrix
   W = np.dot(np.dot(V, D), V.T)

   # multiply by the whitening matrix
   X_white = np.dot(X, W)

   return X_white, W

您还可以使用 SVD 对矩阵进行白化:

def svd_whiten(X):

    U, s, Vt = np.linalg.svd(X, full_matrices=False)

    # U and Vt are the singular matrices, and s contains the singular values.
    # Since the rows of both U and Vt are orthonormal vectors, then U * Vt
    # will be white
    X_white = np.dot(U, Vt)

    return X_white

第二种方式慢一些,但可能在数值上更稳定。

【讨论】:

  • 谢谢! svd不应该对X的协方差矩阵进行吗?
  • @Ran 我认为您将 SVD 与特征分解混淆了。使用 SVD 方法,您无需事先显式计算协方差矩阵 - U 的列将包含 X * X.T 的特征向量,Vt 的行包含X.T * X 的特征向量。由于UVt 的行是正交向量,所以U.dot(Vt) 的协方差矩阵将是恒等式。
  • 我看到的所有其他示例都在协方差矩阵上执行 svd,例如gist.github.com/duschendestroyer/5170087
  • @Ran 您刚刚链接到的示例显示ZCA whitening,这是白化矩阵的许多不同方法之一。对于任何正交矩阵RR * X_white 也将具有恒等协方差。在 ZCA 中,R 被选为U(即X * X.T 的特征向量)。这种特殊的转换导致白化数据尽可能接近X(在最小二乘意义上)。如果您只想要白化数据,您可以按上述方式计算 X_white(如果您不相信我,请查看 X_white.T * X_white 中的值)。
  • 您好,我认为您的协方差矩阵计算假设数据已经以零为中心,对吧?
【解决方案2】:

如果你为此使用 python 的 scikit-learn 库,你可以设置内置参数

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

检查documentation

【讨论】:

    【解决方案3】:

    我认为你需要转置V并取S的平方根。所以公式是

    matrix_to_multiply_with_data = transpose( v ) * s^(-1/2 )

    【讨论】:

      【解决方案4】:

      改用 ZCA 映射

      function [Xw] = whiten(X)
        % Compute and apply the ZCA mapping
        mu_X = mean(X, 1);
        X = bsxfun(@minus, X, mu_X);
        Xw = X / sqrtm(cov(X));
      end 
      

      【讨论】:

      • 这是什么语言?
      • @thistleknot 这不是....世界上最伟大的语言,不....这只是 MATLAB。
      猜你喜欢
      • 2015-03-06
      • 1970-01-01
      • 1970-01-01
      • 2020-07-31
      • 2012-01-13
      • 2020-03-28
      • 1970-01-01
      • 2017-10-01
      • 2015-07-19
      相关资源
      最近更新 更多