source: hypertools/hypertools/gldbm_td.m

Last change on this file was 3, checked in by dtax, 15 years ago

Hypertools, first

File size: 5.7 KB
Line 
1%GLDBM_TD GLDB using top-down criterion (Fisher separability)
2%
3%  W = GLDBM_TD(A)
4%
5% INPUT 
6%  A    Training dataset
7%
8% OUTPUT
9%  W    best bases mapping
10%
11% DESCRIPTION
12% Generalised Best Bases mapping is a feature extraction technique for
13% spectral datasets with two classes.  This function implements the
14% top-down approach starting from a single group with all the wavelengths,
15% recursively identifying the best possible split points.  Groups of
16% adjacent features (wavelengths) are identified in the input dataset such
17% that Fisher criterion is maximized in each group. Output dataset is
18% created by projecting wavelengths in each group to the 1D Fisher
19% subspace.  The procedure is defined for two class problems, if a
20% multi-class dataset is supplied, a cell array of mappings will be
21% computed.  Multi-class classifier, based on this routine, is implemented
22% as PREXP algorithm ALG_GLDBM
23%
24% REFERENCE
25% Kumar,Ghosh,Crawford: Classification of Hyperspectral Data using
26% Best-bases Feature Extraction Algorithm
27%
28% SEE ALSO
29% DATASETS, MAPPINGS, GLDBM
30
31% Copyright: P. Paclik, pavel@ph.tn.tudelft.nl
32% Faculty of Applied Physics, Delft University of Technology
33% P.O. Box 5046, 2600 GA Delft, The Netherlands
34
35% $Id: gldbm_td.m,v 1.5 2005/02/10 15:24:07 pavel Exp $
36
37function [w,crit] = gldbm_td(a,arg2)
38
39        % No arguments given: return untrained mapping.
40
41        if (nargin < 1) | (isempty(a))
42                w = mapping(mfilename);
43                w = setname(w,'Best Bases mapping (top-down)');
44                return
45        end
46
47        if (~exist('arg2','var'))     % Second argument is not a mapping: training.
48
49                isdataset(a);           % Assert that A is a dataset.
50
51                [m,k,c] = getsize(a); M = classsizes(a);
52               
53                if c>2
54                        % for multi-class problem, create all pair-wise extractors
55                        w={};
56                        iter=[];
57                        for i=1:c-1
58                                for j=i+1:c
59                                        fprintf(1,'(%d-%d',i,j);
60                                        t=seldat(a,[i j]);
61                                        eval(['w{i,j}=' mfilename '(t);']);
62                                        fprintf(1,') ');
63                                end
64                        end
65                        return
66                end
67
68                % counter with ten steps
69                t=floor(k/10); % usually, only 80% bands is processed
70                counts=t*ones(1,10);
71                counts(1:mod(m,10))=counts(1:mod(m,10))+1;
72                counts=cumsum(counts);
73               
74                Q=corrcoef(+a);
75                [U,G]=meancov(a);
76
77                m=0;              % level
78                Nm=size(a,2);
79               
80                % in top-down approach, each group of bands is defined by its limits (l,u),
81                % flag saying if it should be processed further and a criterion value:
82               
83                l=1;  % lower bounds of group-bands
84                u=Nm; % upper bounds of group-bands
85                process=1; % should the group be processed?
86                I=0;    % criterion values for each group
87
88                % compute crit for each single band group:
89%               I=crit_eval(l,u,Q,+U(1,:),+U(2,:),G(:,:,1),G(:,:,2));
90
91                while 1
92                   
93                    % we'll go over all the groups and process the processable ones:
94                    temp=find(process==1);
95                    gid=temp(1); % the 1st group in queue to be processed
96%                   fprintf(1,' l=%d,u=%d ',l(gid),u(gid));
97                   
98                    % make possible merges:
99                    % pl and pu refer to the possible left subgroup!
100                    gc=u(gid)-l(gid)+1; % number of possible left subgroups
101                    pl=repmat( l(gid), 1, gc-1 ); % possible beginnings of the left new subgroup
102                    pu=pl(1):u(gid)-1;
103
104                    % eval criterium for left subgroups:
105                    crit1=crit_eval(pl,pu,Q,+U(1,:),+U(2,:),G(:,:,1),G(:,:,2));
106                   
107                    % eval criterion for right subgroups:
108                    crit2=crit_eval(pu+1,repmat(u(gid),1,gc-1),Q,+U(1,:),+U(2,:),G(:,:,1),G(:,:,2));               
109                   
110                    maxval=max([crit1; crit2]);
111                    [maxval,ind]=max(maxval);
112
113                    newcrit=[crit1(ind) crit2(ind)];
114                   
115                    % pu(ind) is the best possible splitting index
116
117                    % decide which of the two new subgroups should be processed further
118                    newprocess=[0 0]; % by default: don't process
119                    if crit1(ind)>I(gid) & ind>1
120                        % decompose the left subgroup
121                        newprocess(1)=1;
122                    end
123                    if crit2(ind)>I(gid) & gc-ind>1
124                        % decompose the left subgroup
125                        newprocess(2)=1;
126                    end
127
128                    % update high-level group definition:
129                    if gid==1
130                        % we're splitting the firrst group
131                        l=[ 1       pu(ind)+1 l(2:end)];
132                        u=[ pu(ind) u(1)      u(2:end)];
133                        process=[newprocess process(2:end)];
134                        I=[newcrit I(2:end)];
135                    elseif gid==Nm
136                        % we're splitting the last group
137                        l=[ l(1:end-1) l(gid) pu(ind)+1];
138                        u=[ u(1:end-1) pu(ind) Nm];
139                        process=[process(1:end-1) newprocess];
140                        I=[I(1:end-1) newcrit];
141                    else
142                        % we're in the middle
143                        l=[ l(1:gid-1) l(gid) pu(ind)+1 l(gid+1:end)];
144                        u=[ u(1:gid-1) pu(ind) u(gid)   u(gid+1:end)];
145                        process=[process(1:gid-1) newprocess process(gid+1:end)];
146                        I=[I(1:gid-1) newcrit I(gid+1:end)];                   
147                    end
148                    fprintf(1,'(%d) ', sum(process));
149                   
150                    if isempty(find(process==1))
151                        % no candidates for progress left, return what
152                        % we have at the moment.
153                        [crit,clf]=crit_eval(l,u,Q,+U(1,:),+U(2,:),G(:,:,1),G(:,:,2));
154
155                        % parameters
156                        pars.clf=clf; pars.l=l; pars.u=u; pars.info_iter=m;
157                        w = mapping(mfilename,'trained',pars,(1:length(l))',k,length(pars.l));
158                        w = setname(w,'Best Bases mapping (top-down)');
159                       
160                        return
161                    end
162                end % while
163        else % Second argument is a a mapping: testing.
164
165                w = arg2;                       
166                pars = getdata(w); % Unpack the mapping.
167                [m,k] = getsize(a);
168
169                % create an output dataset
170                out=[];
171                for i=1:length(pars.clf)
172                        % get the subset of bands...
173                        t=+a(:,pars.l(i):pars.u(i));
174                        % ... and project it to 1D Fisher subspace
175                        out=[out t*pars.clf(i).w];
176                end
177       
178                w = setdat(a,out);
179                w=setfeatlab(w,(1:size(w,2))');
180        end
181
182return
183
184
185
186function [I,clf]=crit_eval(l,u,Q,mua,mub,sigmaa,sigmab)
187
188        I=zeros(1,length(l));
189
190        clf=[];
191        for i=1:length(l)
192               
193                C=min(min( Q( l(i):u(i), l(i):u(i) ) ));
194               
195                W=0.5*( sigmaa( l(i):u(i), l(i):u(i) )+sigmab( l(i):u(i), l(i):u(i) ) );
196                t=( mua( l(i):u(i) ) - mub( l(i):u(i) ) )';
197                B=t*t';
198               
199                w=pinv(W)*t;
200                D=(w'*B*w)/(w'*W*w);
201               
202                I(i)=C*D;
203               
204                clf(i).w=w;
205        end
206       
207       
Note: See TracBrowser for help on using the repository browser.