5

可能重复:
MATLAB 内存不足,但不应如此

我想对大量数据点进行 PCA 分析。更具体地说,我知道数据点的数量和特征的数量size(dataPoints) = [329150 132]在哪里。328150132

我想提取特征向量及其相应的特征值,以便我可以执行 PCA 重建。

但是,当我使用该princomp功能时(即[eigenVectors projectedData eigenValues] = princomp(dataPoints);我收到以下错误:

>> [eigenVectors projectedData eigenValues] = princomp(pointsData);
Error using svd
Out of memory. Type HELP MEMORY for your options.

Error in princomp (line 86)
[U,sigma,coeff] = svd(x0,econFlag); % put in 1/sqrt(n-1) later

但是,如果我使用较小的数据集,我没有问题。

如何在 Matlab 中对我的整个数据集执行 PCA?有人遇到过这个问题吗?

编辑

我已经修改了princomp函数并尝试使用svds而不是svd,但是,我得到了几乎相同的错误。我已经放弃了下面的错误:

Error using horzcat
Out of memory. Type HELP MEMORY for your options.

Error in svds (line 65)
B = [sparse(m,m) A; A' sparse(n,n)];

Error in princomp (line 86)
[U,sigma,coeff] = svds(x0,econFlag); % put in 1/sqrt(n-1) later
4

4 回答 4

5

基于特征分解的解

X'X正如@david 所说,您可以首先计算 PCA 。具体来说,请参见下面的脚本:

sz = [329150 132];
X = rand(sz);

[V D] = eig(X.' * X);

实际上,V保存正确的奇异向量,如果将数据向量成行放置,它会保存主向量。特征值 ,D是每个方向之间的方差。作为标准差的奇异向量被计算为方差的平方根:

S = sqrt(D);

然后,U使用公式 计算左奇异向量X = USV'。请注意,U如果您的数据向量在列中,则指的是主成分。

U = X*V*S^(-1);

让我们重构原始数据矩阵,看看 L2 重构误差:

X2 = U*S*V';
L2ReconstructionError = norm(X(:)-X2(:))

它几乎为零:

L2ReconstructionError =
  6.5143e-012

如果您的数据向量在列中,并且您想将数据转换为特征空间系数,您应该这样做U.'*X

在我的中等 64 位桌面中,此代码段大约需要 3 秒。

基于随机 PCA 的解决方案

或者,您可以使用基于随机 PCA 的更快的近似方法。请在 Cross Validated 中查看我的答案。您可以直接计算fsvd和获取UandV而不是使用eig.

如果数据量太大,您可以使用随机 PCA。但是,我认为以前的方式足以满足您给出的尺寸。

于 2012-10-03T10:36:35.850 回答
1

我的猜测是你有一个庞大的数据集。您不需要所有的 svd 系数。在这种情况下,使用svds代替svd

直接取自 Matlab 帮助:

 s = svds(A,k) computes the k largest singular values and associated singular vectors of matrix A.

从你的问题,我知道你不svd直接打电话。但是您不妨看看princomp(它是可编辑的!)并更改调用它的行。

于 2012-10-02T21:18:41.470 回答
0

您可能需要在计算中以某种方式计算n x n矩阵,也就是说:

329150 * 329150 * 8btyes ~ 866GB`

的空间,这解释了为什么你会得到一个内存错误。似乎有一种计算 pca 的有效方法princomp(X, 'econ'),我建议您尝试一下。

更多关于这个在stackoverflowmathworks ..

于 2012-10-02T23:26:16.423 回答
0

手动计算 X'X (132x132) 和 svd。或者找到 NIPALS 脚本。

于 2012-10-03T00:44:15.937 回答