MATLAB内存不足,但实际上应该不会出现这种情况。

9
我正在尝试使用已标准化的数据运用PCA,方法是使用princomp(x)。该数据为<16 x 1036800 double>。由于这是一台新电脑,内存为24GB,用于数据挖掘。然而,内存不足是可以预见的,但MATLAB在执行PCA时是否实际上已经耗尽了内存?或者MATLAB没有充分利用内存?任何信息或想法都会有所帮助。(我可能需要增加虚拟内存,但认为24GB应该已经足够。)

这可能更适合在Serverfault上提问。 - Miro A.
4
@Miro A.:嗯,不是这样的。与服务器或网络无关。 - nico
@nico 你可能是对的。我想的是Superuser.com,而不是serverfault——我的错。 - Miro A.
1
不要忘记,为了保存单个矩阵/向量,您需要有一个连续的内存空间可用...这肯定不是24GB。在总可用内存之后,“memory”命令还应告诉您单个变量的最大大小(最大连续空间)。 - Hoki
3个回答

20
对于一个大小为n-by-p的数据矩阵,PRINCOMP将返回一个大小为p-by-p的系数矩阵,其中每一列都是使用原始维度表示的主成分,因此在您的情况下,您将创建一个大小为:的输出矩阵。
1036800*1036800*8 bytes ~ 7.8 TB

考虑使用PRINCOMP(X,'econ')仅返回具有显着方差的主成分。
或者,考虑执行PCA by SVD:在您的情况下n<<p,且协方差矩阵无法计算。因此,不需要分解p×p矩阵XX',只需分解较小的n×n矩阵X'X即可。参考this paper

编辑:

这是我的实现,该函数的输出与PRINCOMP(至少前三个)匹配:

function [PC,Y,varPC] = pca_by_svd(X)
    % PCA_BY_SVD
    %   X      data matrix of size n-by-p where n<<p
    %   PC     columns are first n principal components
    %   Y      data projected on those PCs
    %   varPC  variance along the PCs
    %

    X0 = bsxfun(@minus, X, mean(X,1));     % shift data to zero-mean
    [U,S,PC] = svd(X0,'econ');             % SVD decomposition
    Y = X0*PC;                             % project X on PC
    varPC = diag(S'*S)' / (size(X,1)-1);   % variance explained
end

我刚刚在我的4GB机器上试了一下,运行得非常好:

» x = rand(16,1036800);
» [PC, Y, varPC] = pca_by_svd(x);
» whos
  Name             Size                     Bytes  Class     Attributes

  PC         1036800x16                 132710400  double              
  Y               16x16                      2048  double              
  varPC            1x16                       128  double              
  x               16x1036800            132710400  double              

更新:

princomp函数已被弃用,推荐使用在R2012b引入的pca函数,该函数包含更多选项。


2
对于那些感兴趣的人,请参见Math.SE上关于PCA和SVD之间关系的这个解释 - Amro
1
请问您为什么使用varPC = diag(S'*S)' / size(X,1);而不是varPC = diag(S'*S)' / (size(X,1)-1);?在我的情况下,将(size(X,1)-1)作为分母与princomp给出了相同的结果。这是否与“样本方差与总体方差”相同? - Sibbs Gambling
1
@SibbsGambling:谢谢,你说得对,我已经修复了代码。 - Amro
我可以问两个跟进的问题吗?(1) 为什么用这种方法,有时会得到一个“翻转”的特征向量(与princomp相比)?我知道这对于定义本身并不重要,但当我使用不同的特征向量进行投影时,最终得到的投影数据是不同的。(2) 我理解我们中心化数据的原因。为什么我们不投影未中心化的数据?投影处理后的数据而不是原始数据似乎有点偏离。 - Sibbs Gambling
1
@SibbsGambling:抱歉回复晚了;(1)这里有一些相关答案https://dev59.com/fmnWa4cB1Zd3GeqP6Psp#13041293,https://dev59.com/vHXYa4cB1Zd3GeqP64Dr#18152804,https://dev59.com/-WYr5IYBdhLWcg3waJZT#13704582,http://scicomp.stackexchange.com/a/16240/386 (2)我们通常做的是先减去平均值,进行PCA变换和数据投影,然后再加上原始平均值(毕竟只是一个平移)。 - Amro

1

Matlab在矩阵大小方面有硬编码限制。请查看this link。如果您认为您没有达到这些限制,那么您可能在代码中有一个错误并且实际上已经超出了限制。


0
Mathworks工程师Stuart McGarrity录制了一场精彩的网络研讨会,介绍了诊断技术和常见解决方案。如果您的数据确实在允许范围内,问题可能是内存碎片化 - 这是很容易解决的

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接