Matlab - 如何在庞大的数据集上计算PCA

时间:2012-10-02 21:14:53

标签: matlab pca

  

可能重复:
  MATLAB is running out of memory but it should not be

我想对大量数据点进行PCA分析。更具体地说,我有size(dataPoints) = [329150 132],其中328150是数据点的数量,132是要素的数量。

我想提取特征向量及其相应的特征值,以便我可以进行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 个答案:

答案 0 :(得分:5)

基于特征分解的解决方案

你可以先在X'X上计算PCA,如@david所说。具体来说,请参阅下面的脚本:

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的更快速的近似方法。请参阅my answer in Cross Validated。您可以直接计算fsvd并获取UV,而不是使用eig

如果数据量太大,您可以使用随机PCA。但是,我认为前面的方式对于你给出的大小就足够了。

答案 1 :(得分:1)

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

直接从Matlab帮助:

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

根据您的问题,我们了解到您不直接致电svd。但你也可以看看princomp(它是可编辑的!)并改变调用它的行。

答案 2 :(得分:0)

您可能需要在计算中以某种方式计算 n by n 矩阵,即:

329150 * 329150 * 8btyes ~ 866GB`
空间

解释了为什么会出现内存错误。似乎有一种使用princomp(X, 'econ')计算pca的有效方法,我建议你试一试。

有关stackoverflowmathworks ..

的详情

答案 3 :(得分:0)

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