⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mypca.m

📁 主成分分析中特征根等输出
💻 M
字号:
function [T,P,ssq,Ro,Rv,Lo,Lv] = mypca(X,nF,options)
% function [T,P,ssq,Ro,Rv,Lo,Lv] = mypca(X,nF,options)
% 040706 FvdB
% Principal Component Analysis bilinear factor model.
%
% in :
% X (objects x variables) data block
% nF (1 x 1) number of factors/principal components
% options (1 x 3) tolerance for convergence, maximum number of iterations 
%    and use SVD/SVDNaN-imputation i.s.o. NIPALS to estimate parameters (default 1e-8, 2000 and 1=yes/SVDNaN)
%
% out : 
% T (objects x nF) scores
% P (variables x nF) loadings
% ssq (nF x 1) cumulative sum of squares
% Ro (objects x nF) object residuals
% Rv (variables x nF) variable residuals
% Lo (objects x nF) object leverages
% Lv (variables x nF) variable leverages
%
% uses:
% svdnan.m

if nargin < 2
    help mypca
    return
elseif nargin == 2
    options = [1e-8 2000 1];
else
    if (length(options) == 1)
        options = [options 2000 1];
    elseif (length(options) == 2)
        options = [options 1];
    end
end

[nX,mX] = size(X);
if nF > nX
    s = ['ERROR: number of objects (' int2str(nX) ') is to small to compute ' int2str(nF) ' factors'];
    error(s)
end
if nF > mX
    s = ['ERROR: number of variables (' int2str(mX) ') is to small to compute ' int2str(nF) ' factors'];
    error(s)
end

T = zeros(nX,nF);
P = zeros(mX,nF);
ssq = zeros(nF,1);
MV = sum(sum(isnan(X)));
if options(3)
    [T,D,P] = svdnan(X,nF,[0 options(1:2)]);
    T = T*D;
    if MV
        Xmv = sparse(isnan(X));
        X(Xmv) = 0;
    end
    ssqX = sum(sum(X.^2));
    for a=1:nF
        X = X - T(:,a)*P(:,a)';
        if MV
            X(Xmv) = 0;
        end
        ssq(a) = (ssqX - sum(sum(X.^2)))/ssqX;
        if (nargout > 3)
            Ro(:,a) = sqrt(sum(X.^2,2));
            Rv(:,a) = sqrt(sum(X.^2,1))';
            Lo(:,a) = diag(T(:,1:a)*pinv(T(:,1:a)'*T(:,1:a))*T(:,1:a)');
            Lv(:,a) = diag(P(:,1:a)*P(:,1:a)');
        end
    end
else
    if MV
        Xmv = sparse(isnan(X));
        X(Xmv) = 0;
    end
    ssqX = sum(sum(X.^2));
    for a=1:nF
        iter = 0;
        [aa,aaa] = max(sum(X.^2,1));
        T(:,a) = X(:,aaa);
        t_old = T(:,a)*10;
        if MV
            while (sum((t_old - T(:,a)).^2)/sum(t_old.^2) > options(1)) & (iter <= options(2))
                iter = iter + 1;
                t_old = T(:,a);
                P(:,a) = X'*T(:,a);
                for aa=1:mX
                    c = (T(~Xmv(:,aa),a)'*T(~Xmv(:,aa),a));
                    if (abs(c) > eps)
                        P(aa,a) = P(aa,a)/c;
                    end
                end
                P(:,a) = P(:,a)/norm(P(:,a));
                T(:,a) = X*P(:,a);
                for aa=1:nX
                    c = (P(~Xmv(aa,:),a)'*P(~Xmv(aa,:),a));
                    if (abs(c) > eps)
                        T(aa,a) = T(aa,a)/c;
                    end
                end
            end
        else
            while (sum((t_old - T(:,a)).^2)/sum(t_old.^2) > options(1)) & (iter < options(2))
                iter = iter + 1;
                t_old = T(:,a);
                P(:,a) = X'*T(:,a)/(T(:,a)'*T(:,a));
                P(:,a) = P(:,a)/norm(P(:,a));
                T(:,a) = X*P(:,a)/(P(:,a)'*P(:,a));
            end
        end
        if iter == options(2)
            s = ['WARNING: maximum number of iterations (' num2str(options(2)) ') reached before convergence'];
            disp(s)
        end
        X = X - T(:,a)*P(:,a)';
        if MV
            X(Xmv) = 0;
        end
        ssq(a) = (ssqX - sum(sum(X.^2)))/ssqX;
        if (nargout > 3)
            Ro(:,a) = sqrt(sum(X.^2,2));
            Rv(:,a) = sqrt(sum(X.^2,1))';
            Lo(:,a) = diag(T(:,1:a)*pinv(T(:,1:a)'*T(:,1:a))*T(:,1:a)');
            Lv(:,a) = diag(P(:,1:a)*P(:,1:a)');
        end
    end
end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -