1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 | % Temel/Ana Bilesenler Cozumlemesi/Analizi (Principle Component Analysis)
%
% Girdiler: sampleMat -> Her satiri bir ornek vektorden olusan matris,
% n -> (opsiyonel) istenilen ozvektor ve ozdeger sayisi
% Ciktilar: V -> "sampleMat" ile verilen vektorlerin ana yonleri (ozvektorleri).
% "V" matrisinin her sutunu bir ozvektordur. Soldan saga dogru baskinlik azalir.
% D -> "V" ozvektorlerine ait ozdegerler. "D" vektorunun her elemani, "V"
% matrisinin ilgili sutunundaki ozvektor yonundeki degisintiyi (varyasyonu) gosterir.
%
% Ornek: 3 boyutta olan 5 nokta olsun. Bunlari her satira bir tanesi gelecek sekilde yazalim.
% x = [1 2 1; 0 2 1; 0 3 2; 2 4 1; 1 3 0], n = 2 olursa V iki sutundan olusur ve ilk sutun
% en cok degisintinin oldugu yonu, ikinci sutun da sonraki
% baskin yonu gosterir.
% Not: Eger ornek sayisi, boyut sayisindan azsa hizli olmasi icin
% Eckart-Young teoremini kullanir.
function [V,D] = pca(sampleMat,n)
nSamples = size(sampleMat,1);
nDim = size(sampleMat,2);
% Ortalama vektoru bul
meanSample = mean(sampleMat,1);
% sampleMat'taki tum elemanlardan ortalamayi cikararak normalizasyon yap
sampleMat = sampleMat - repmat(meanSample, nSamples, 1);
% Eger boyut sayisi ornek sayisindan coksa, hizli olmasi icin
% sampleMat'in transpozesini al
if nDim > nSamples
sampleMat = sampleMat.';
end
% Dagilimin kovaryansini bul
C = sampleMat.' * sampleMat ./ nSamples;
% Ozdegerler (D) ve ozvektorleri (V) bul
% Hatirla ki: A*V = V*D ve V'nin her sutunu bir ozvektor
[V,D] = eig(C);
D = diag(D);
% Ozdegerleri buyukten kucuge siralamak gerekli. Matlab tersinden
% buldugu icin degerleri ters dondur.
D = flipud(D); % Sutun vektorunu altust et
V = fliplr(V); % Matrisin sagdan sola aynasini al
% Eger hizlandirma kullanildiysa Buldugumuz sutunlardan ozvektor bulup
% ozvektorleri normalize etmeliyiz. Ozdegerler aynidir. Bak: Eckart-Young Teoremi
if nDim > nSamples
V = sampleMat * V;
for i = 1:nSamples
normV = norm(V(:,i));
V(:,i) = V(:,i) ./ normV;
end
end
if exist('n','var') % n verildiyse, ilk n degeri dondur
if n > nDim
error('Isdeginiz ozvektor sayisi bulduklarimdan fazla!')
end
D = D(1:n);
V = V(:,1:n);
end
|