【问题标题】:Inaccuracies w/ prcomp? R lang PCA for eigenfacesprcomp 不准确?用于特征脸的 R lang PCA
【发布时间】:2014-08-24 04:36:28
【问题描述】:

我的问题是:如果有一个我们想要在其上进行 PCA 的矩阵,其中特征的数量大大超过了试验的数量,为什么 prcomp 的行为不符合预期(或者我错过了什么)?

以下是问题摘要,full code is herecompressed 7MB data source is here(未压缩为 55MB)、target image is here

我的确切情况是我有一个矩阵 p x n 矩阵 X(p = 特征,n = 试验),其中试验是拍摄的面部照片,特征是照片中的像素(所以 32256 x 148矩阵)。我想要做的是找到该矩阵的主成分得分向量。由于求协方差矩阵 XX^T 代价太大,一个简单的解决方法是求 X^TX 的特征向量 (v_i) 并通过 X (Xv_i) more info 变换它们。

XTX <- t(X) %*% X # missing the 1 / n - 1 for cov matrix b/c we normalize later anyway
eigen <- eigen(XTX)
eigenvectors.XTX.col <- eigen$vectors

principal.component.scores <- apply(eigenvectors.XTX.col, 2, function(c) {
  normalize.vector(X %*% matrix(c, ncol = 1))
})

在我的例子中,主成分分数是特征脸,可以用来成功重建目标脸,如下所示:http://cl.ly/image/260w0N0u0Z3y(参考我的full code for how

将 X 传递给 prcomp 应该做一些等效的事情,但结果与上述本土方式不同:

pca <- prcomp(X)
pca$x # right size, but wrong pc scores

使用pca$x重建人脸的结果不是完全废话,而是更糟糕:http://cl.ly/image/2p19360u2P43

我还检查了在 t(x) 上使用 prcomp 会产生不同的旋转矩阵,因此 prcomp 正在做一些花哨的事情,但在幕后却有些神秘。我从here 知道prcomp 正在使用SVD 来计算主成分加载向量而不是特征分解,但这不应该导致任何错误(或者我认为......)。

使用内置prcomp方法的正确方法是什么,一定有方法吧?

【问题讨论】:

  • 由于“数学”,该方法无法解决您的问题。您应该至少拥有与变量一样多的观测值,但最好是前者更多。
  • 感谢@RomanLuštrik 的评论! This source 证实了您对 princomp 方法所说的话,但正如我在下面的答案中惊讶地发现的那样,并非您需要比变量更多的观察结果(这在基因组学等某些学科中是不可能的,或者即使在这里有面部识别)。相反,这里的问题是prcomp 中的一些令人讨厌的默认值以及缺乏规范化。抱歉我的问题中的蹩脚问题!

标签: r pca svd eigenvector


【解决方案1】:

哇,答案一点也不好玩,而是与prcomp 方法中的默认参数有关:

为了解决这个问题,我首先查看了the R source of prcomp,发现旋转矩阵应该等于svd(X)$v。在 R 命令行上检查这一点证明,我的 X (data here) 没有。这是因为即使有默认参数 scale = Fprcomp,prcomp 仍然会运行 R scale 方法,如果只是为了使矩阵居中,默认为 True,如 here 所示。就我而言,这很糟糕,因为我传递的数据已经居中(减去平均图像)。

因此,使用prcomp(X, center = F) 重新运行将产生一个等于svd(X)$v 的旋转矩阵,正如预期的那样。从现在开始,prcomp 在构造 prcomp(X, center = F)$x 时犯的唯一“错误”将是不对列进行规范化,因此它们每一个都仅与我在上面在我的代码中引用的 principal.component.scores 矩阵的标量倍数相差。如果不规范化prcomp(X, center = F)$x,结果会更好,但并不像这里看到的那样好: http://cl.ly/image/3u2y3m1h2S0o

但是通过pca.x.norm &lt;- apply(pca$x, 2, normalize.vector) 标准化后,prcomp 在重建人脸时的结果是相同的: http://cl.ly/image/24390O3x0A0x

tl;dr - prcomp 即使使用参数 scale = F 也会意外地将数据居中,此外,出于特征面的目的,您需要对 prcomp(X, center = F)$x 的列进行规范化,然后一切都会按预期工作!

【讨论】:

    猜你喜欢
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-09
    • 2018-07-31
    • 2013-10-07
    • 1970-01-01
    • 2016-03-22
    相关资源
    最近更新 更多