サイズnxpのデータ行列の場合、PRINCOMP
はサイズp x pの係数行列を返します。ここで、各列は元の次元を使用して表現された主成分であるため、この場合、サイズの出力行列を作成します。
1036800*1036800*8 bytes ~ 7.8 TB
PRINCOMP(X,'econ')
大幅な差異のあるPCのみを返すために使用することを検討してください
あるいは、SVDによってPCAを実行することを検討してください:あなたの場合n<<p
、共分散行列を計算することは不可能です。したがって、p行p列の行列を分解する代わりにXX'
、小さいn行n列の行列のみを分解するだけで十分X'X
です。参考までにこのペーパーを参照してください。
編集:
これが私の実装です。この関数の出力はPRINCOMPの出力と一致します(とにかく最初の3つ):
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
関数は非推奨になりpca
、R2012bで導入されました。これには、さらに多くのオプションが含まれています。