PCA代码及其注释

function [eigvector, eigvalue] = PCA(data, options)
%PCA Principal Component Analysis
%
% Usage:
%       [eigvector, eigvalue] = PCA(data, options)
%       [eigvector, eigvalue] = PCA(data)
%
%             Input:
%               data       - Data matrix. Each row vector of fea is a data point.
%
%     options.ReducedDim   - The dimensionality of the reduced subspace. If 0,
%                         all the dimensions will be kept.
%                         Default is 0.
%
%             Output:
%               eigvector - Each column is an embedding function, for a new
%                           data point (row vector) x,  y = x*eigvector
%                           will be the embedding result of x.
%               eigvalue  - The sorted eigvalue of PCA eigen-problem.
%
% Examples:
% fea = rand(7,10);
%           options=[];
%           options.ReducedDim=4;
% [eigvector,eigvalue] = PCA(fea,4);
%           Y = fea*eigvector;
%



if (~exist('options','var'))
    options = [];
end                  %构建options矩阵


ReducedDim = 0;
if isfield(options,'ReducedDim')
    ReducedDim = options.ReducedDim;  %判断输入的options参数中是否有ReducedDim这个值,可有可没有,有的话就赋值options的ReducedDim
end




[nSmp,nFea] = size(data);   %判断ReducedDim的值与输入原数据矩阵的列数的大小
if (ReducedDim > nFea) || (ReducedDim <=0)  %如果输入的ReducedDim的值比列数大或者小于等于0.就执行 ReducedDim = nFea;
    ReducedDim = nFea;
end




if issparse(data)    %查看数据的数据是否为稀疏矩阵 如果为稀疏矩阵将他改为全矩阵,全矩阵(包括0)和稀疏矩阵是matlab中存储稀疏矩阵的两种形式
    data = full(data);
end
sampleMean = mean(data,1); %求出矩阵每一列的平均值
data = (data - repmat(sampleMean,nSmp,1)); %将求出的平均值进行行数的扩充,nSmp倍;将原数据每一行都减去这个平均值   *****核心


[eigvector, eigvalue] = mySVD(data',ReducedDim);  %调用mySVD函数,求出特征值,特征向量     *****核心
eigvalue = full(diag(eigvalue)).^2;  %diag(eigvalue)取值特征值矩阵的对角元素,并对每一个元素进行平方


if isfield(options,'PCARatio')    %查看options中是否有PCARatio这个属性
    sumEig = sum(eigvalue);   %将特征值的元素的和赋值给sunEig
    sumEig = sumEig*options.PCARatio;  %特征值的和与输入的PCARatio的乘积赋值给sumEig
    sumNow = 0;     %设置变量(变量名为sumNow)
    for idx = 1:length(eigvalue)   %根据特征值的长度进行for循环,每加入一个特征值,就将sumNow的值与特征值的和进行比较,如果值大于特征值的总和,循环结束
        sumNow = sumNow + eigvalue(idx);
        if sumNow >= sumEig
            break;
        end
    end
    eigvector = eigvector(:,1:idx);  %由for循环终止时,idx确定最大值,将特征向量中1~idx列的值全部取出 作为特征向量
end

猜你喜欢

转载自blog.csdn.net/qq_35774189/article/details/76534539
PCA