[18] | 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) |
---|
[79] | 31 | W = prmapping(mfilename,h); |
---|
[18] | 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 | |
---|
[79] | 148 | W = prmapping('parzend_map','trained',par,getlablist(d),k,c); |
---|
[18] | 149 | W = setname(W,'Parzen DisRep Classifier'); |
---|
| 150 | W = setcost(W,d); |
---|
| 151 | |
---|
| 152 | return; |
---|