可能重复:
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)
基于特征分解的解决方案
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并获取U而V不是使用eig.
如果数据量太大,您可以使用随机PCA.但是,我认为之前的方式足以满足您的规模.