1 | %PARZENDDC Parzen density based classifier for dissimilarity data |
---|
2 | % |
---|
3 | % [W,H] = PARZENDDC(D) |
---|
4 | % W = PARZENDDC(D,H) |
---|
5 | % |
---|
6 | % INPUT |
---|
7 | % D Dissimilarity dataset |
---|
8 | % H Smoothing parameters (optional; default: estimated from D) |
---|
9 | % |
---|
10 | % OUTPUT |
---|
11 | % W Trained Parzen classifier |
---|
12 | % H Smoothing parameters, estimated from the data |
---|
13 | % |
---|
14 | % DESCRIPTION |
---|
15 | % |
---|
16 | % SEE ALSO |
---|
17 | % DATASETS, MAPPINGS, PARZEND_MAP |
---|
18 | |
---|
19 | % Copyright: R.P.W. Duin, r.p.w.duin@prtools.org |
---|
20 | % Faculty EWI, Delft University of Technology |
---|
21 | % P.O. Box 5031, 2600 GA Delft, The Netherlands |
---|
22 | |
---|
23 | function [W,h] = parzenddc(d,h) |
---|
24 | |
---|
25 | prtrace(mfilename); |
---|
26 | |
---|
27 | if nargin < 2, h = []; end |
---|
28 | |
---|
29 | % No input arguments: return an untrained mapping. |
---|
30 | if nargin == 0 | isempty(d) |
---|
31 | W = prmapping(mfilename,h); |
---|
32 | W = setname(W,'Parzen DisRep Classifier'); |
---|
33 | return; |
---|
34 | end |
---|
35 | |
---|
36 | if nargin < 2 | isempty(h); |
---|
37 | %prwarning(5,'Smoothing parameters not specified, estimated from the data.'); |
---|
38 | %error('Smoothing parameter estimation not yet implemented') |
---|
39 | h = []; |
---|
40 | end |
---|
41 | |
---|
42 | islabtype(d,'crisp','soft'); |
---|
43 | isvaldfile(d,2,2); % at least 2 objects per class, 2 classes |
---|
44 | d = testdatasize(d); |
---|
45 | d = testdatasize(d,'objects'); |
---|
46 | |
---|
47 | [m,k,c] = getsize(d); |
---|
48 | nlab = getnlab(d); |
---|
49 | |
---|
50 | if ~isempty(h) % Take user settings for smoothing parameters. |
---|
51 | |
---|
52 | nlab = getnlab(d); |
---|
53 | if length(h) == 1 |
---|
54 | hh = repmat(h,m,1); |
---|
55 | elseif length(h) == c |
---|
56 | hh = zeros(m,1); |
---|
57 | for j=1:c |
---|
58 | J = find(nlab==j); |
---|
59 | hh(J) = h(j); |
---|
60 | end |
---|
61 | else |
---|
62 | error('Smoothing parameter has wrong size') |
---|
63 | end |
---|
64 | |
---|
65 | else % Estimate smoothing parameters (copied and adapted from parzenc) |
---|
66 | |
---|
67 | %error('Not yet implemented') |
---|
68 | |
---|
69 | % compute all object distances |
---|
70 | D = +d; |
---|
71 | dim = intrdim(D); |
---|
72 | hinit = max(D(:)); % for sure a too high value |
---|
73 | D = D.^2 + diag(inf*ones(1,m)); |
---|
74 | % find object weights q |
---|
75 | q = classsizes(d); |
---|
76 | |
---|
77 | % find for each object its class freqency |
---|
78 | of = q(nlab); |
---|
79 | |
---|
80 | % find object weights q |
---|
81 | p = getprior(d); |
---|
82 | %a = setprior(a,p); |
---|
83 | q = p(nlab)./q(nlab); |
---|
84 | |
---|
85 | % initialise |
---|
86 | h = hinit; |
---|
87 | %h = 2.5 |
---|
88 | L = -inf; |
---|
89 | Ln = 0; |
---|
90 | z = 0.01^(1/dim); % initial step size |
---|
91 | |
---|
92 | % iterate |
---|
93 | |
---|
94 | len1 = prprogress([],'parzenddc: error optimization smoothing parameter: '); |
---|
95 | len2 = prprogress([],' %6.4f %6.4f ',0,0); |
---|
96 | iter = 0; |
---|
97 | prwaitbar(100,'parzenc: Optimizing smoothing parameter',m > 100); |
---|
98 | while abs(Ln-L) > 0.0001 & z < 1 |
---|
99 | % In L we store the best performance estimate found so far. |
---|
100 | % Ln is the actual performance (for the actual h) |
---|
101 | % If Ln > L we improve the bound L, and so we rest it. |
---|
102 | iter = iter+1; |
---|
103 | prwaitbar(100,100-100*exp(-iter/10)); |
---|
104 | if Ln > L, L = Ln; end |
---|
105 | |
---|
106 | r = -0.5/(h^2); |
---|
107 | F = q(ones(1,m),:)'.*exp(D*r); % density contributions |
---|
108 | FS = sum(F)*((m-1)/m); IFS = find(FS>0); % joint density distribution |
---|
109 | if islabtype(d,'crisp'); |
---|
110 | G = sum(F .* (nlab(:,ones(1,m)) == nlab(:,ones(1,m))')); |
---|
111 | else |
---|
112 | G = zeros(1,m); |
---|
113 | for j=1:c |
---|
114 | G = G + sum(F .* (d.targets(:,j) * d.targets(:,j)')); |
---|
115 | end |
---|
116 | end |
---|
117 | G = G.*(of-1)./of; % true-class densities |
---|
118 | % performance estimate, neglect zeros |
---|
119 | |
---|
120 | en = max(p)*ones(1,m); |
---|
121 | en(IFS) = (G(IFS))./FS(IFS); |
---|
122 | Ln = exp(sum(log(en+realmin))/m); |
---|
123 | |
---|
124 | closemess([],len2); |
---|
125 | len2 = prprogress([],' %6.4f %6.4f ',h,Ln); |
---|
126 | |
---|
127 | if Ln < L % compute next estimate |
---|
128 | z = sqrt(z); % adjust stepsize up (recall: 0 < z < 1) |
---|
129 | h = h / z; % if we don't improve, increase h (approach h_opt from below) |
---|
130 | else |
---|
131 | z = z*z; |
---|
132 | h = h * z; % if we improve, decrease h (approach h_opt from above) |
---|
133 | end |
---|
134 | %disp([Ln,L,z,h]) |
---|
135 | end |
---|
136 | closemess([],len1+len2); |
---|
137 | hh = h*ones(m,1); |
---|
138 | prwaitbar(0); |
---|
139 | |
---|
140 | end |
---|
141 | |
---|
142 | par.objects = [1:m]'; |
---|
143 | par.prior = getprior(d); |
---|
144 | par.nlab = getnlab(d); |
---|
145 | par.smoothpar = hh; |
---|
146 | par.weights = ones(m,1); |
---|
147 | |
---|
148 | W = prmapping('parzend_map','trained',par,getlablist(d),k,c); |
---|
149 | W = setname(W,'Parzen DisRep Classifier'); |
---|
150 | W = setcost(W,d); |
---|
151 | |
---|
152 | return; |
---|