A = [1 2 -2 0 1; 1 -1.3 0 2 -1];
H = eye(5)-0.2*ones(5);
C = A*H;
B = cov(C(1,:),C(2,:),1); % this cov uses n-1 as denominator
[V,L] = eig(B);
L = real(diag(L));
[L,I] = sort(L,'descend');
X = V'*C;
Y = V(:,I(1))*X(I(1),:);
% fix ratio to see orthogonal projection
a = max([abs(C(1,:)) abs(C(2,:)) abs(Y(1,:)) abs(Y(2,:))]);
axis([-a a -a a]);
pbaspect([1 1 1]);
hold on
for i = 1:5
plot(C(1,i),C(2,i), '.', 'MarkerSize', 18, 'Color',[0 0 1]);
plot(Y(1,i),Y(2,i), '.', 'MarkerSize', 18, 'Color',[1 0 0]);
line([C(1,i);Y(1,i)],[C(2,i);Y(2,i)]);
if i < 5
line([Y(1,i);Y(1,i+1)],[Y(2,i);Y(2,i+1)]);
end
end
function Y = pca(X,d)
m = size(X,1);
n = size(X,2);
H = eye(n)-(1/n)*ones(n);
C = X*H;
B = C*C'; % this cov uses n-1 as denominator
[V,L] = eig(B);
L = real(diag(L));
[~,I] = sort(L,'descend');
D = V'*C;
Y = zeros(m,n);
Y(1:d,:) = D(I(1:d),:);
hold on;
if d == 2
for i = 1:n
plot(Y(1,i),Y(2,i),'.', 'MarkerSize', 12, 'Color',[0 i/n i/n]);
end
else
for i = 1:n
plot3(Y(1,i),Y(2,i),Y(3,i),'.', 'MarkerSize', 12, 'Color',[0 i/n i/n]);
end
end
打開 matlab,輸入 swiss roll 或其他現成資料矩陣 X,然後執行 pca(X,3); 即可。
ps. 可用 scatter 指令取代 plot。
ps. 當然可以用 svd 來寫,此處是配合教學所以用 eigen-decomposition.