一个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
    评论
### 回答1: PCA(主成分分析)是一种常用的数据降维方法,可以将高维数据映射到低维空间,同时保留数据的最重要的信息。下面是一个简单的PCA代码示例,使用Python语言实现: ``` import numpy as np def pca(X, num_components): # 去中心化数据 X_mean = np.mean(X, axis=0) X_centered = X - X_mean # 计算协方差矩阵 cov_matrix = np.cov(X_centered.T) # 计算特征值和特征向量 eigenvalues, eigenvectors = np.linalg.eig(cov_matrix) # 选择前num_components个特征向量 idx = eigenvalues.argsort()[::-1][:num_components] eigenvectors = eigenvectors[:, idx] # 转换数据到新的空间 X_transformed = np.dot(X_centered, eigenvectors) return X_transformed # 测试代码 X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) X_transformed = pca(X, 2) print(X_transformed) ``` 在这个示例中,我们首先对数据进行去中心化处理,然后计算协方差矩阵,接着计算特征值和特征向量。我们选择前num_components个特征向量,将数据映射到新的空间,并返回降维后的数据。最后,我们用一个简单的测试数据来测试我们的代码,输出新的降维数据。 ### 回答2: PCA(Principal Component Analysis)是一种常用的降维方法,可以将高维的数据映射到一个低维的子空间上。 下面是一个使用Python编写的主要代码示例,实现PCA: ```python import numpy as np def pca(X, k): # 数据标准化 X = (X - np.mean(X, axis=0)) / np.std(X, axis=0) # 计算协方差矩阵 cov_matrix = np.cov(X.T) # 计算特征值和特征向量 eigenvalues, eigenvectors = np.linalg.eig(cov_matrix) # 对特征值从大到小进行排序 sorted_index = np.argsort(eigenvalues)[::-1] sorted_eigenvalues = eigenvalues[sorted_index] sorted_eigenvectors = eigenvectors[:, sorted_index] # 选择前k个特征向量 k_eigenvectors = sorted_eigenvectors[:, :k] # 将数据投影到选取的特征向量上 X_pca = np.dot(X, k_eigenvectors) return X_pca # 测试代码 # 创建一个随机数据集 np.random.seed(0) X = np.random.rand(100, 3) # 使用PCA降维到2维 X_pca = pca(X, 2) print(X_pca.shape) ``` 以上代码中,pca函数接受两个参数:X为输入的数据集,k为要保留的主成分数量。首先对数据进行标准化,然后计算协方差矩阵,接着求解特征值和特征向量,并按特征值从大到小对其进行排序。最后选择前k个特征向量,将数据投影到这些特征向量上,得到降维后的数据X_pca。在示例中,我们生成一个随机的3维数据集,并将其降维到2维,最后打印降维后的数据形状。 ### 回答3: PCA(Principal Component Analysis,主成分分析)是一种常用的降维数据压缩算法。下面是一个用Python实现PCA的简单示例代码: ```python import numpy as np def pca(data, n_components): # 数据中心化 mean = np.mean(data, axis=0) centered_data = data - mean # 计算协方差矩阵 covariance_matrix = np.cov(centered_data, rowvar=False) # 计算特征值和特征向量 eigenvalues, eigenvectors = np.linalg.eig(covariance_matrix) # 选取前n个特征向量 eigenvectors_sorted = eigenvectors[:, np.argsort(-eigenvalues)[:n_components]] # 将数据投影到选取的特征向量上 transformed_data = np.dot(centered_data, eigenvectors_sorted) return transformed_data # 示例数据 data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]) # 调用PCA函数,降维至2维 transformed_data = pca(data, n_components=2) # 打印降维后的数据 print(transformed_data) ``` 以上代码实现了一个简单的PCA函数,将输入的数据降维至指定的维度。在示例中,输入数据一个4行3列的矩阵,调用PCA函数将数据降维至2维,并打印降维后的数据。 该实现基于numpy库,首先对输入数据进行中心化处理,然后计算协方差矩阵,接着使用numpy提供的特征值分解函数求解特征值和特征向量。最后,根据所选取的特征向量对中心化后的数据进行投影,得到降维后的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

u小鬼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值