一个PCA加速技巧

EVD-PCA

PCA推导:PCA主成分分析法浅理解
请添加图片描述
具体数值如10304×10304是我机器学习课程实验的数据集参数,这里关注数字量级即可。

code

% EVD-PCA数据降维
% input: D×N output:K×N
function [Z, K] = EVD_PCA(X, K, weight)
    fprintf('Running EVD-PCA dimensionality reduction...\n');
    if exist('eigenData.mat', 'file') == 0
        [~, N] = size(X);
        %% Step 1: Center the data
%         mu  = mean(X);
%         X = X - mu;   !err
        mu  = mean(X, 2);
        X = X - mu * ones(1, N);
        %% Step 2: Compute the covariance matrix
        S = X * X' / N; % D×D
%         size(S)
        %% Step 3: Do an eigendecomposition of S
        [V, D] = eig(S);    % !time-consuming
        % S*V=V*D,其中D为特征值的对角矩阵,V对应列为特征向量
        % (D×D)*(D×E)=(D×E)*(E×E),其中E为特征值个数,D为原数据维度(区分对角矩阵D)
        
        %% Step 4: Take first K leading eigenvector
        eigenVal = diag(D); % 特征值序列
        [~, sortedIndex] = sort(eigenVal, 'descend');
        eigenVec = V(:, sortedIndex);   % 对应特征向量构筑矩阵
        eigenVal = eigenVal(sortedIndex);
        save('eigenData.mat', 'eigenVec', 'eigenVal');
    else 
        load('eigenData.mat');
    end
    %% 检查是否传入有效K,否则基于weight动态定义K
    % 前K个特征值之和占特征值之和的比例达到weight
    if K < 0
       sumVal = sum(eigenVal);
       for i = 1 : length(eigenVal)
           newRate = sum(eigenVal(1 : i), 1) / sumVal;
           if newRate >= weight
               K = i; break;
           end
       end
       fprintf('Dynamically define K to %d\n', K);
    end
    U = eigenVec(:, 1 : K); % (D×K)
    
    %% Step 5: Calc the final K dim. projection of data
    Z = U' * X; % (K×N)=(K×D)*(D×N)
    
    fprintf('EVD-PCA done\n');
end

SVD-PCA

请添加图片描述
以上是我发现的一个小技巧,并通过测试发现,SVD-PCA方法准确率和标准EVD-PCA方法几乎相同,而效率大大提升!

code

% SVD-PCA数据降维
% input: D×N output:K×N
function [Z] = SVD_PCA(X, K)
    fprintf('Running SVD-PCA dimensionality reduction...\n');
    [D, N] = size(X);    % D:feature dimension
    %% Step 1: Center the data
    mu  = mean(X, 2);
    X = X - mu * ones(1, N);

    %% Step 2: Compute the A^{T}A
    Mat = X' * X;
    %% Step 3: Do an eigendecomposition of A^{T}A
    % 利用左奇异值矩阵U进行特征维度压缩,即减少X的行数
    [V, S] = eig(Mat);  % N×N
    %% Step 4: Take first K leading eigenvector of A^{T}A then build 
    %% Left single matrix U
    S = diag(S);
    [S, si] = sort(S, 'descend');

    eigenVec = zeros(N, K);
    eigenVal = zeros(1, K);
    for i = 1 : K
        eigenVec(:, i) = V(:, si(i));
        eigenVal(i) = S(i);
    end
    
    rU = zeros(D, K);   % reconstructed matrix U
    for i = 1 : K
        rU(:, i) = X * eigenVec(:, i) / sqrt(eigenVal(i));    % 奇异值≈sqrt(特征值)
    end
%     save('svdData', 'eigenVec', 'eigenVal', 'rU');
    
    %% Step 5: Calc the final K dim. projection of data
    Z = rU' * X; % (K×N)=(K×D)*(D×N)
    
    fprintf('SVD-PCA done\n');
end

Comparison

Accuracy

K值SVD-PCA(×100%)EVD-PCA(×100%)
10.1600000000000000.175000000000000
20.3850000000000000.368750000000000
40.7400000000000000.756250000000000
80.9300000000000000.918750000000000
160.9600000000000000.937500000000000
320.9700000000000000.975000000000000
480.9650000000000000.975000000000000
640.9550000000000000.981250000000000
800.9500000000000000.975000000000000
960.9550000000000000.968750000000000

Time consumption

请添加图片描述
在这里插入图片描述
可以看到两种方法10次不同K值PCA部分的总用时分别为1.482s162.713s,而且实际上后者利用了文件存储的结果。效率的差异源于对两个不同矩阵(10304×10304 vs. 400×400)做evd.

Conclusion

由于测试集大小在120-200之间,以上准确率可以认为几乎相同。因此我们可以得出结论:SVD-PCA在该人脸数据集表现更优。
或者说在 D ≫ N D\gg N DN的情况下通过SVD做协方差矩阵 S S S的特征值分解是可行的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

u小鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值