0. PCA란?
PCA는 principal component analysis의 약자로 주어진 데이터의 principal component를 찾는 알고리즘이다. 그리고 principal component는 주어진 데이터를 가장 잘 표현하는 축인 basis를 의미한다.
즉 PCA를 이해하기 위해서는 주어진 데이터를 잘 표현하는 것이 무엇인지를 알아야한다. PCA에서는 분산을 최대로하는 basis를 찾는 것을 의미한다. 밑의 구현에서 보면 알겠지만 데이터를 col 방향으로 쌓은 matrix D가 있을 때 분산은 D'*D이고, D'*D의 eigenvector들이 principal component들이다. 데이터의 손실률은 eigenvalue의 합에 반비례한다.
1. PCA 결과
[그림을 클릭하면 크게 보임]
2. 매트랩 코드
%% PCA는 기본적으로 unsupervised learning이다.
clc;
clear all;
close all;
%% 데이터를 만든다.
c_var = 2;
c1count = 100;
c1mean = [10 4 1];
c1var = diag([c_var c_var c_var]);
c2count = 100;
c2mean = [2 10 5];
c2var = diag([c_var c_var c_var]);
c3count = 100;
c3mean = [3 1 10];
c3var = diag([c_var c_var c_var]);
% 데이터를 하나로 묶는다.
data = [ ones(c1count, 1)*c1mean+randn(c1count, 3)*sqrt(c1var) ...
; ones(c2count, 1)*c2mean+randn(c2count, 3)*sqrt(c2var) ...
; ones(c3count, 1)*c3mean+randn(c3count, 3)*sqrt(c3var) ...
];
%% PCA를 수행한다.
[coeff, score] = princomp(data);
% 차원을 줄이지 않았을 때 (3차원)
data_3d = data*coeff;
% 차원을 하나 줄였을 때 (2차원)
data_2d = data*coeff(:, 1:2);
% 차원을 두 개 줄였을 때 (1차원)
data_1d = data*coeff(:, 1:2);
%% 결과를 그림으로 확인한다.
fig1 = figure('Position', [100 100 1300 800], 'Name' ...
, 'Note that PCA is basically an Unsupervised learning algorithm. Lable information is not used. ');
% reference
subplot(221); hold on;
h1 = plot3( data(1:c1count, 1) ...
, data(1:c1count, 2) ...
, data(1:c1count, 3), 'ro');
h2 = plot3( data(c1count+1:c1count+c2count, 1) ...
, data(c1count+1:c1count+c2count, 2) ...
, data(c1count+1:c1count+c2count, 3), 'go');
h3 = plot3( data(c1count+c2count+1:c1count+c2count+c3count, 1) ...
, data(c1count+c2count+1:c1count+c2count+c3count, 2) ...
, data(c1count+c2count+1:c1count+c2count+c3count, 3), 'bo');
hold off; grid on;title('Reference data'); legend([h1 h2 h3], 'type1', 'type2', 'type3');
view(-33, 24); axis tight;
% 3D
subplot(222); hold on;
h1 = plot3( data_3d(1:c1count, 1) ...
, data_3d(1:c1count, 2) ...
, data_3d(1:c1count, 3), 'ro');
h2 = plot3( data_3d(c1count+1:c1count+c2count, 1) ...
, data_3d(c1count+1:c1count+c2count, 2) ...
, data_3d(c1count+1:c1count+c2count, 3), 'go');
h3 = plot3( data_3d(c1count+c2count+1:c1count+c2count+c3count, 1) ...
, data_3d(c1count+c2count+1:c1count+c2count+c3count, 2) ...
, data_3d(c1count+c2count+1:c1count+c2count+c3count, 3), 'bo');
hold off; grid on;title('PCA dim no reduced data'); legend([h1 h2 h3], 'type1', 'type2', 'type3');
view(-80, 56); axis tight;
% 2D
subplot(223); hold on;
h1 = plot( data_2d(1:c1count, 1) ...
, data_2d(1:c1count, 2), 'ro');
h2 = plot( data_2d(c1count+1:c1count+c2count, 1) ...
, data_2d(c1count+1:c1count+c2count, 2), 'go');
h3 = plot( data_2d(c1count+c2count+1:c1count+c2count+c3count, 1) ...
, data_2d(c1count+c2count+1:c1count+c2count+c3count, 2), 'bo');
hold off; grid on;title('PCA 3D->2D data'); legend([h1 h2 h3], 'type1', 'type2', 'type3');
axis tight;
% 1D
subplot(224); hold on;
h1 = plot( data_1d(1:c1count, 1), 'ro-');
h2 = plot( data_1d(c1count+1:c1count+c2count, 1), 'go-');
h3 = plot( data_1d(c1count+c2count+1:c1count+c2count+c3count, 1), 'bo-');
hold off; grid on;title('PCA 3D->1D data'); legend([h1 h2 h3], 'type1', 'type2', 'type3');
axis tight;
set(fig1,'PaperPositionMode','auto')
print (fig1 , '-dpng', ['fig_pca', num2str(0), '.png']) ;
%%
3. 추가 - 매트랩의 princomp를 svd로 구현하기
%% PCA를 수행한다.
[coeff, score, latent] = princomp(data);
%% svd를 이용해서 PCA를 하기
x = data;
[n, p] = size(x);
avg = ones(n, 1)*mean(x, 1);
x0 = x - avg;
[U D V] = svd(x0', 0);
evs = diag(D);
evs = evs ./ sqrt(n-1);
evs = evs.^2;
% U가 coeff와 같고, evs가 latent와 같다.
'Enginius > Machine Learning' 카테고리의 다른 글
Gaussian Process Approximations (PITC, D2FAS) (0) | 2013.10.15 |
---|---|
What is the future of Big data (0) | 2013.07.22 |
Dirichlet Process (DP) (2) | 2013.07.05 |
Latent Dirichlet Allocation (0) | 2013.06.22 |
Convex Optimization of Graph Laplacian (0) | 2013.05.31 |