-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathKPCA.m
114 lines (98 loc) · 3.38 KB
/
KPCA.m
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
function [eigvector, eigvalue] = KPCA(data, options)
%KPCA Kernel Principal Component Analysis
%
% Usage:
% [eigvector, eigvalue] = KPCA(data, options)
%
% Input:
% data -
% if options.Kernel = 0
% Data matrix. Each row vector of fea is a data
% point.
% if options.Kernel = 1
% Kernel matrix.
%
% options - Struct value in Matlab. The fields in options
% that can be set:
% Kernel - 1: data is actually the kernel matrix.
% 0: ordinary data matrix.
% Default: 0
%
% Please see constructKernel.m for other Kernel options.
%
% ReducedDim - The dimensionality of the reduced subspace. If 0,
% all the dimensions will be kept. Default is 30.
%
% Output:
% eigvector - Each column is an embedding function, for a new
% data point (row vector) x, y = K(x,:)*eigvector
% will be the embedding result of x.
% K(x,:) = [K(x1,x),K(x2,x),...K(xm,x)]
% eigvalue - The sorted eigvalue of PCA eigen-problem.
%
% Examples:
% options.KernelType = 'Gaussian';
% options.t = 1;
% options.ReducedDim = 4;
% fea = rand(7,10);
% [eigvector,eigvalue] = KPCA(fea,options);
% feaTest = rand(3,10);
% Ktest = constructKernel(feaTest,fea,options)
% Y = Ktest*eigvector;
%
%Reference:
%
% Bernhard Schölkopf, Alexander Smola, Klaus-Robert Müller, “Nonlinear
% Component Analysis as a Kernel Eigenvalue Problem", Neural Computation,
% 10:1299-1319, 1998.
%
%
% version 1.1 --Dec./2011
% version 1.0 --April/2005
%
% Written by Deng Cai (dengcai AT gmail.com)
%
MAX_MATRIX_SIZE = 1600; % You can change this number according your machine computational power
EIGVECTOR_RATIO = 0.1; % You can change this number according your machine computational power
ReducedDim = 30;
if isfield(options,'ReducedDim')
ReducedDim = options.ReducedDim;
end
if isfield(options,'Kernel') && options.Kernel
K = data;
else
K = constructKernel(data,[],options);
end
clear data;
nSmp = size(K,1);
if (ReducedDim > nSmp) || (ReducedDim <=0)
ReducedDim = nSmp;
end
sumK = sum(K,2);
H = repmat(sumK./nSmp,1,nSmp);
K = K - H - H' + sum(sumK)/(nSmp^2);
K = max(K,K');
clear H;
if nSmp > MAX_MATRIX_SIZE && ReducedDim < nSmp*EIGVECTOR_RATIO
% using eigs to speed up!
option = struct('disp',0);
[eigvector, eigvalue] = eigs(K,ReducedDim,'la',option);
eigvalue = diag(eigvalue);
else
[eigvector, eigvalue] = eig(K);
eigvalue = diag(eigvalue);
[dump, index] = sort(-eigvalue);
eigvalue = eigvalue(index);
eigvector = eigvector(:,index);
end
if ReducedDim < length(eigvalue)
eigvalue = eigvalue(1:ReducedDim);
eigvector = eigvector(:, 1:ReducedDim);
end
maxEigValue = max(abs(eigvalue));
eigIdx = find(abs(eigvalue)/maxEigValue < 1e-6);
eigvalue (eigIdx) = [];
eigvector (:,eigIdx) = [];
for i=1:length(eigvalue) % normalizing eigenvector
eigvector(:,i)=eigvector(:,i)/sqrt(eigvalue(i));
end;