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

Sim*_*mon 5 matlab pca

可能重复:
MATLAB内存不足但不应该

我想对一个庞大的数据集进行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
Run Code Online (Sandbox Code Playgroud)

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

如何在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
Run Code Online (Sandbox Code Playgroud)

pet*_*hor 5

基于特征分解的解决方案

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

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

[V D] = eig(X.' * X);
Run Code Online (Sandbox Code Playgroud)

实际上,V保持正确的奇异向量,如果将数据向量放在行中,它将保留主要向量.特征值D是每个方向之间的差异.作为标准偏差的奇异向量计算为方差的平方根:

S = sqrt(D);
Run Code Online (Sandbox Code Playgroud)

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

U = X*V*S^(-1);
Run Code Online (Sandbox Code Playgroud)

让我们重建原始数据矩阵并查看L2重建错误:

X2 = U*S*V';
L2ReconstructionError = norm(X(:)-X2(:))
Run Code Online (Sandbox Code Playgroud)

它几乎为零:

L2ReconstructionError =
  6.5143e-012
Run Code Online (Sandbox Code Playgroud)

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

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

基于随机PCA的解决方案

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

如果数据量太大,您可以使用随机PCA.但是,我认为之前的方式足以满足您的规模.