wolffd@0
|
1 function sM = som_supervised(sData,varargin)
|
wolffd@0
|
2
|
wolffd@0
|
3 %SOM_SUPERVISED SOM training which utilizes class information.
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % sM = som_supervised(sData, [ArgID, value,...]))
|
wolffd@0
|
6 %
|
wolffd@0
|
7 % Input and output arguments ([]'s are optional)
|
wolffd@0
|
8 % sData (struct) data struct, the class information is
|
wolffd@0
|
9 % taken from the first column of .labels field
|
wolffd@0
|
10 % [argID, (string) See below. These are given as
|
wolffd@0
|
11 % value] (varies) 'argID', value -pairs.
|
wolffd@0
|
12 %
|
wolffd@0
|
13 % sMap (struct) map struct
|
wolffd@0
|
14 %
|
wolffd@0
|
15 % Here are the argument IDs and corresponding values:
|
wolffd@0
|
16 % 'munits' (scalar) the preferred number of map units
|
wolffd@0
|
17 % 'msize' (vector) map grid size
|
wolffd@0
|
18 % 'mask' (vector) BMU search mask, size dim x 1
|
wolffd@0
|
19 % 'name' (string) map name
|
wolffd@0
|
20 % 'comp_names' (string array / cellstr) component names, size dim x 1
|
wolffd@0
|
21 % 'tracking' (scalar) how much to report, default = 1
|
wolffd@0
|
22 % The following values are unambiguous and can therefore
|
wolffd@0
|
23 % be given without the preceeding argument ID:
|
wolffd@0
|
24 % 'algorithm' (string) training algorithm: 'seq' or 'batch'
|
wolffd@0
|
25 % 'mapsize' (string) do you want a 'small', 'normal' or 'big' map
|
wolffd@0
|
26 % Any explicit settings of munits or msize override this.
|
wolffd@0
|
27 % 'topol' (struct) topology struct
|
wolffd@0
|
28 % 'som_topol','sTopol' = 'topol'
|
wolffd@0
|
29 % 'lattice' (string) map lattice, 'hexa' or 'rect'
|
wolffd@0
|
30 % 'shape' (string) map shape, 'sheet', 'cyl' or 'toroid'
|
wolffd@0
|
31 % 'neigh' (string) neighborhood function, 'gaussian', 'cutgauss',
|
wolffd@0
|
32 % 'ep' or 'bubble'
|
wolffd@0
|
33 %
|
wolffd@0
|
34 % For more help, try 'type som_supervised', or check out online documentation.
|
wolffd@0
|
35 % See also SOM_MAKE, SOM_AUTOLABEL.
|
wolffd@0
|
36
|
wolffd@0
|
37 %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
38 %
|
wolffd@0
|
39 % som_supervised
|
wolffd@0
|
40 %
|
wolffd@0
|
41 % PURPOSE
|
wolffd@0
|
42 %
|
wolffd@0
|
43 % Creates, initializes and trains a supervised SOM by taking the
|
wolffd@0
|
44 % class-identity into account.
|
wolffd@0
|
45 %
|
wolffd@0
|
46 % SYNTAX
|
wolffd@0
|
47 %
|
wolffd@0
|
48 % sMap = som_supervised(sData);
|
wolffd@0
|
49 % sMap = som_supervised(...,'argID',value,...)
|
wolffd@0
|
50 % sMap = som_make(...,value,...);
|
wolffd@0
|
51 %
|
wolffd@0
|
52 % DESCRIPTION
|
wolffd@0
|
53 %
|
wolffd@0
|
54 % Creates, initializes and trains a supervised SOM. It constructs the
|
wolffd@0
|
55 % training data by adding 1-of-N -coded matrix to the original data
|
wolffd@0
|
56 % based on the class information in the .labels field. The dimension
|
wolffd@0
|
57 % of vectors after the process is (the old dimension + number of
|
wolffd@0
|
58 % different classes). In each vector, one of the new components has
|
wolffd@0
|
59 % value '1' (this depends on the class of the vector), and others '0'.
|
wolffd@0
|
60 % Calls SOM_MAKE to construct the map. Then the class of each map unit
|
wolffd@0
|
61 % is determined by taking maximum over these added components, and a
|
wolffd@0
|
62 % label is give accordingly. Finally, the extra components (the
|
wolffd@0
|
63 % 1-of-N -coded ones) are removed.
|
wolffd@0
|
64 %
|
wolffd@0
|
65 % REFERENCES
|
wolffd@0
|
66 %
|
wolffd@0
|
67 % Kohonen, T., "Self-Organizing Map", 2nd ed., Springer-Verlag,
|
wolffd@0
|
68 % Berlin, 1995, pp. 160-161.
|
wolffd@0
|
69 % Kohonen, T., Mäkivasara, K., Saramäki, T., "Phonetic Maps -
|
wolffd@0
|
70 % Insightful Representation of Phonological Features For
|
wolffd@0
|
71 % Speech Recognition", In proceedings of International
|
wolffd@0
|
72 % Conference on Pattern Recognition (ICPR), Montreal, Canada,
|
wolffd@0
|
73 % 1984, pp. 182-185.
|
wolffd@0
|
74 %
|
wolffd@0
|
75 % REQUIRED INPUT ARGUMENTS
|
wolffd@0
|
76 %
|
wolffd@0
|
77 % sData The data to use in the training.
|
wolffd@0
|
78 % (struct) A data struct. '.comp_names' as well as '.name'
|
wolffd@0
|
79 % is copied to the map. The class information is
|
wolffd@0
|
80 % taken from the first column of '.labels' field.
|
wolffd@0
|
81 %
|
wolffd@0
|
82 % OPTIONAL INPUT ARGUMENTS
|
wolffd@0
|
83 %
|
wolffd@0
|
84 % argID (string) Argument identifier string (see below).
|
wolffd@0
|
85 % value (varies) Value for the argument (see below).
|
wolffd@0
|
86 %
|
wolffd@0
|
87 % The optional arguments can be given as 'argID',value -pairs. If an
|
wolffd@0
|
88 % argument is given value multiple times, the last one is used.
|
wolffd@0
|
89 % Here are the argument IDs and corresponding values:
|
wolffd@0
|
90 % 'munits' (scalar) the preferred number of map units - this may
|
wolffd@0
|
91 % change a bit, depending on the properties of the data
|
wolffd@0
|
92 % 'msize' (vector) map grid size
|
wolffd@0
|
93 % 'mask' (vector) BMU search mask, size dim x 1
|
wolffd@0
|
94 % 'name' (string) map name
|
wolffd@0
|
95 % 'comp_names' (string array / cellstr) component names, size dim x 1
|
wolffd@0
|
96 % 'tracking' (scalar) how much to report, default = 1. This parameter
|
wolffd@0
|
97 % is also passed to the training functions.
|
wolffd@0
|
98 % The following values are unambiguous and can therefore
|
wolffd@0
|
99 % be given without the preceeding argument ID:
|
wolffd@0
|
100 % 'algorithm' (string) training algorithm: 'seq' or 'batch' (default)
|
wolffd@0
|
101 % 'mapsize' (string) do you want a 'small', 'normal' or 'big' map
|
wolffd@0
|
102 % Any explicit settings of munits or msize (or topol)
|
wolffd@0
|
103 % override this.
|
wolffd@0
|
104 % 'topol' (struct) topology struct
|
wolffd@0
|
105 % 'som_topol','sTopol' = 'topol'
|
wolffd@0
|
106 % 'lattice' (string) map lattice, 'hexa' or 'rect'
|
wolffd@0
|
107 % 'shape' (string) map shape, 'sheet', 'cyl' or 'toroid'
|
wolffd@0
|
108 % 'neigh' (string) neighborhood function, 'gaussian', 'cutgauss',
|
wolffd@0
|
109 % 'ep' or 'bubble'
|
wolffd@0
|
110 %
|
wolffd@0
|
111 % OUTPUT ARGUMENTS
|
wolffd@0
|
112 %
|
wolffd@0
|
113 % sMap (struct) SOM -map struct
|
wolffd@0
|
114 %
|
wolffd@0
|
115 % EXAMPLES
|
wolffd@0
|
116 %
|
wolffd@0
|
117 % To simply train a map with default parameters:
|
wolffd@0
|
118 %
|
wolffd@0
|
119 % sMap = som_supervised(sData);
|
wolffd@0
|
120 %
|
wolffd@0
|
121 % With the optional arguments, the initialization and training can be
|
wolffd@0
|
122 % influenced. To change map size, use 'msize', 'munits' or 'mapsize'
|
wolffd@0
|
123 % arguments:
|
wolffd@0
|
124 %
|
wolffd@0
|
125 % sMap = som_supervised(D,'mapsize','big'); or
|
wolffd@0
|
126 % sMap = som_supervised(D,'big');
|
wolffd@0
|
127 % sMap = som_supervised(D,'munits', 100);
|
wolffd@0
|
128 % sMap = som_supervised(D,'msize', [20 10]);
|
wolffd@0
|
129 %
|
wolffd@0
|
130 % Argument 'algorithm' can be used to switch between 'seq' and 'batch'
|
wolffd@0
|
131 % algorithms. 'batch' is the default, so to use 'seq' algorithm:
|
wolffd@0
|
132 %
|
wolffd@0
|
133 % sMap = som_supervised(D,'algorithm','seq'); or
|
wolffd@0
|
134 % sMap = som_supervised(D,'seq');
|
wolffd@0
|
135 %
|
wolffd@0
|
136 % The 'tracking' argument can be used to control the amout of reporting
|
wolffd@0
|
137 % during training. The argument is used in this function, and it is
|
wolffd@0
|
138 % passed to the training functions. To make the function work silently
|
wolffd@0
|
139 % set it to 0.
|
wolffd@0
|
140 %
|
wolffd@0
|
141 % sMap = som_supervised(D,'tracking',0);
|
wolffd@0
|
142 %
|
wolffd@0
|
143 % SEE ALSO
|
wolffd@0
|
144 %
|
wolffd@0
|
145 % som_make Create, initialize and train Self-Organizing map.
|
wolffd@0
|
146 % som_autolabel Label SOM/data set based on another SOM/data set.
|
wolffd@0
|
147
|
wolffd@0
|
148 % Contributed to SOM Toolbox vs2, Feb 2nd, 2000 by Juha Parhankangas
|
wolffd@0
|
149 % Copyright (c) by Juha Parhankangas
|
wolffd@0
|
150 % http://www.cis.hut.fi/projects/somtoolbox/
|
wolffd@0
|
151
|
wolffd@0
|
152 % Juha Parhankangas 050100
|
wolffd@0
|
153
|
wolffd@0
|
154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
155
|
wolffd@0
|
156 D0 = sData.data;
|
wolffd@0
|
157 [c,n,classlabels] = class2num(sData.labels(:,1));
|
wolffd@0
|
158
|
wolffd@0
|
159 %%%%%%%% Checking arguments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
160
|
wolffd@0
|
161 if ~isstruct(sData)
|
wolffd@0
|
162 error('Argument ''sData'' must be a ''som_data'' -struct.');
|
wolffd@0
|
163 else
|
wolffd@0
|
164 data_name = sData.name;
|
wolffd@0
|
165 comp_names = sData.comp_names;
|
wolffd@0
|
166 comp_norm = sData.comp_norm;
|
wolffd@0
|
167 end
|
wolffd@0
|
168
|
wolffd@0
|
169 [dlen,dim] = size(sData.data);
|
wolffd@0
|
170
|
wolffd@0
|
171 % defaults
|
wolffd@0
|
172
|
wolffd@0
|
173 mapsize = '';
|
wolffd@0
|
174 sM = som_map_struct(dim+n);
|
wolffd@0
|
175 sTopol = sM.topol;
|
wolffd@0
|
176 munits = prod(sTopol.msize); % should be zero
|
wolffd@0
|
177 mask = sM.mask;
|
wolffd@0
|
178 name = sM.name;
|
wolffd@0
|
179 neigh = sM.neigh;
|
wolffd@0
|
180 tracking = 1;
|
wolffd@0
|
181 algorithm = 'batch';
|
wolffd@0
|
182
|
wolffd@0
|
183 %%%% changes to defaults (checking varargin) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
184
|
wolffd@0
|
185 i=1;
|
wolffd@0
|
186 while i <= length(varargin)
|
wolffd@0
|
187 argok = 1;
|
wolffd@0
|
188 if ischar(varargin{i})
|
wolffd@0
|
189 switch varargin{i},
|
wolffd@0
|
190 % argument IDs
|
wolffd@0
|
191 case 'mask',
|
wolffd@0
|
192 i=i+1;
|
wolffd@0
|
193 mask = varargin{i};
|
wolffd@0
|
194 case 'munits',
|
wolffd@0
|
195 i=i+1;
|
wolffd@0
|
196 munits = varargin{i};
|
wolffd@0
|
197 case 'msize',
|
wolffd@0
|
198 i=i+1;
|
wolffd@0
|
199 sTopol.msize = varargin{i};
|
wolffd@0
|
200 munits = prod(sTopol.msize);
|
wolffd@0
|
201 case 'mapsize',
|
wolffd@0
|
202 i=i+1;
|
wolffd@0
|
203 mapsize = varargin{i};
|
wolffd@0
|
204 case 'name',
|
wolffd@0
|
205 i=i+1;
|
wolffd@0
|
206 name = varargin{i};
|
wolffd@0
|
207 case 'comp_names',
|
wolffd@0
|
208 i=i+1;
|
wolffd@0
|
209 comp_names = varargin{i};
|
wolffd@0
|
210 case 'lattice',
|
wolffd@0
|
211 i=i+1;
|
wolffd@0
|
212 sTopol.lattice = varargin{i};
|
wolffd@0
|
213 case 'shape',
|
wolffd@0
|
214 i=i+1;
|
wolffd@0
|
215 sTopol.shape = varargin{i};
|
wolffd@0
|
216 case {'topol','som_topol','sTopol'},
|
wolffd@0
|
217 i=i+1;
|
wolffd@0
|
218 sTopol = varargin{i};
|
wolffd@0
|
219 munits = prod(sTopol.msize);
|
wolffd@0
|
220 case 'neigh',
|
wolffd@0
|
221 i=i+1;
|
wolffd@0
|
222 neigh = varargin{i};
|
wolffd@0
|
223 case 'tracking',
|
wolffd@0
|
224 i=i+1;
|
wolffd@0
|
225 tracking = varargin{i};
|
wolffd@0
|
226 case 'algorithm',
|
wolffd@0
|
227 i=i+1;
|
wolffd@0
|
228 algorithm = varargin{i};
|
wolffd@0
|
229 % unambiguous values
|
wolffd@0
|
230 case {'hexa','rect'},
|
wolffd@0
|
231 sTopol.lattice = varargin{i};
|
wolffd@0
|
232 case {'sheet','cyl','toroid'},
|
wolffd@0
|
233 sTopol.shape = varargin{i};
|
wolffd@0
|
234 case {'gaussian','cutgauss','ep','bubble'},
|
wolffd@0
|
235 neigh = varargin{i};
|
wolffd@0
|
236 case {'seq','batch'},
|
wolffd@0
|
237 algorithm = varargin{i};
|
wolffd@0
|
238 case {'small','normal','big'},
|
wolffd@0
|
239 mapsize = varargin{i};
|
wolffd@0
|
240 otherwise argok=0;
|
wolffd@0
|
241 end
|
wolffd@0
|
242 elseif isstruct(varargin{i}) & isfield(varargin{i},'type'),
|
wolffd@0
|
243 switch varargin{i}(1).type,
|
wolffd@0
|
244 case 'som_topol',
|
wolffd@0
|
245 sTopol = varargin{i};
|
wolffd@0
|
246 otherwise argok=0;
|
wolffd@0
|
247 end
|
wolffd@0
|
248 else
|
wolffd@0
|
249 argok = 0;
|
wolffd@0
|
250 end
|
wolffd@0
|
251 if ~argok,
|
wolffd@0
|
252 disp(['(som_supervised) Ignoring invalid argument #' num2str(i+1)]);
|
wolffd@0
|
253 end
|
wolffd@0
|
254 i = i+1;
|
wolffd@0
|
255 end
|
wolffd@0
|
256
|
wolffd@0
|
257 %%%%%%%% Action %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
258
|
wolffd@0
|
259
|
wolffd@0
|
260
|
wolffd@0
|
261 % constructing the training data by adding 1-of-N -coded matrix to the
|
wolffd@0
|
262 % original data.
|
wolffd@0
|
263
|
wolffd@0
|
264 [dlen,dim] = size(D0);
|
wolffd@0
|
265
|
wolffd@0
|
266 Dc = zeros(dlen,n);
|
wolffd@0
|
267
|
wolffd@0
|
268 for i=1:dlen
|
wolffd@0
|
269 if c(i)
|
wolffd@0
|
270 Dc(i,c(i)) = 1;
|
wolffd@0
|
271 end
|
wolffd@0
|
272 end
|
wolffd@0
|
273
|
wolffd@0
|
274 D = [D0, Dc];
|
wolffd@0
|
275
|
wolffd@0
|
276 % initialization and training
|
wolffd@0
|
277
|
wolffd@0
|
278 sD = som_data_struct(D,...
|
wolffd@0
|
279 'name',data_name);
|
wolffd@0
|
280
|
wolffd@0
|
281 sM = som_make(sD,...
|
wolffd@0
|
282 'mask',mask,...
|
wolffd@0
|
283 'munits',munits,...
|
wolffd@0
|
284 'name',data_name,...
|
wolffd@0
|
285 'tracking',tracking,...
|
wolffd@0
|
286 'algorithm',algorithm,...
|
wolffd@0
|
287 'mapsize',mapsize,...
|
wolffd@0
|
288 'topol',sTopol,...
|
wolffd@0
|
289 'neigh',neigh);
|
wolffd@0
|
290
|
wolffd@0
|
291 % add labels
|
wolffd@0
|
292
|
wolffd@0
|
293 for i=1:prod(sM.topol.msize),
|
wolffd@0
|
294 [dummy,class] = max(sM.codebook(i,dim+[1:n]));
|
wolffd@0
|
295 sM.labels{i} = classlabels{class};
|
wolffd@0
|
296 end
|
wolffd@0
|
297
|
wolffd@0
|
298 %sD.labels = sData.labels;
|
wolffd@0
|
299 %sM = som_autolabel(sM,sD,'vote');
|
wolffd@0
|
300
|
wolffd@0
|
301 % remove extra components and modify map -struct
|
wolffd@0
|
302
|
wolffd@0
|
303 sM.codebook = sM.codebook(:,1:dim);
|
wolffd@0
|
304 sM.mask = sM.mask(1:dim);
|
wolffd@0
|
305 sM.comp_names = sData.comp_names;
|
wolffd@0
|
306 sM.comp_norm = sData.comp_norm;
|
wolffd@0
|
307
|
wolffd@0
|
308 % remove extras from sM.trainhist
|
wolffd@0
|
309
|
wolffd@0
|
310 for i=1:length(sM.trainhist)
|
wolffd@0
|
311 if sM.trainhist(i).mask
|
wolffd@0
|
312 sM.trainhist(i).mask = sM.trainhist(i).mask(1:dim);
|
wolffd@0
|
313 end
|
wolffd@0
|
314 end
|
wolffd@0
|
315
|
wolffd@0
|
316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
317
|
wolffd@0
|
318 function [numbers, n, names] = class2num(class)
|
wolffd@0
|
319
|
wolffd@0
|
320 names = {};
|
wolffd@0
|
321 numbers = zeros(length(class),1);
|
wolffd@0
|
322
|
wolffd@0
|
323 for i=1:length(class)
|
wolffd@0
|
324 if ~isempty(class{i}) & ~any(strcmp(class{i},names))
|
wolffd@0
|
325 names=cat(1,names,class(i));
|
wolffd@0
|
326 end
|
wolffd@0
|
327 end
|
wolffd@0
|
328
|
wolffd@0
|
329 n=length(names);
|
wolffd@0
|
330
|
wolffd@0
|
331 tmp_numbers = (1:n)';
|
wolffd@0
|
332
|
wolffd@0
|
333 for i=1:length(class)
|
wolffd@0
|
334 if ~isempty(class{i})
|
wolffd@0
|
335 numbers(i,1) = find(strcmp(class{i},names));
|
wolffd@0
|
336 end
|
wolffd@0
|
337 end
|