wolffd@0: function sM = som_supervised(sData,varargin) wolffd@0: wolffd@0: %SOM_SUPERVISED SOM training which utilizes class information. wolffd@0: % wolffd@0: % sM = som_supervised(sData, [ArgID, value,...])) wolffd@0: % wolffd@0: % Input and output arguments ([]'s are optional) wolffd@0: % sData (struct) data struct, the class information is wolffd@0: % taken from the first column of .labels field wolffd@0: % [argID, (string) See below. These are given as wolffd@0: % value] (varies) 'argID', value -pairs. wolffd@0: % wolffd@0: % sMap (struct) map struct wolffd@0: % wolffd@0: % Here are the argument IDs and corresponding values: wolffd@0: % 'munits' (scalar) the preferred number of map units wolffd@0: % 'msize' (vector) map grid size wolffd@0: % 'mask' (vector) BMU search mask, size dim x 1 wolffd@0: % 'name' (string) map name wolffd@0: % 'comp_names' (string array / cellstr) component names, size dim x 1 wolffd@0: % 'tracking' (scalar) how much to report, default = 1 wolffd@0: % The following values are unambiguous and can therefore wolffd@0: % be given without the preceeding argument ID: wolffd@0: % 'algorithm' (string) training algorithm: 'seq' or 'batch' wolffd@0: % 'mapsize' (string) do you want a 'small', 'normal' or 'big' map wolffd@0: % Any explicit settings of munits or msize override this. wolffd@0: % 'topol' (struct) topology struct wolffd@0: % 'som_topol','sTopol' = 'topol' wolffd@0: % 'lattice' (string) map lattice, 'hexa' or 'rect' wolffd@0: % 'shape' (string) map shape, 'sheet', 'cyl' or 'toroid' wolffd@0: % 'neigh' (string) neighborhood function, 'gaussian', 'cutgauss', wolffd@0: % 'ep' or 'bubble' wolffd@0: % wolffd@0: % For more help, try 'type som_supervised', or check out online documentation. wolffd@0: % See also SOM_MAKE, SOM_AUTOLABEL. wolffd@0: wolffd@0: %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: % wolffd@0: % som_supervised wolffd@0: % wolffd@0: % PURPOSE wolffd@0: % wolffd@0: % Creates, initializes and trains a supervised SOM by taking the wolffd@0: % class-identity into account. wolffd@0: % wolffd@0: % SYNTAX wolffd@0: % wolffd@0: % sMap = som_supervised(sData); wolffd@0: % sMap = som_supervised(...,'argID',value,...) wolffd@0: % sMap = som_make(...,value,...); wolffd@0: % wolffd@0: % DESCRIPTION wolffd@0: % wolffd@0: % Creates, initializes and trains a supervised SOM. It constructs the wolffd@0: % training data by adding 1-of-N -coded matrix to the original data wolffd@0: % based on the class information in the .labels field. The dimension wolffd@0: % of vectors after the process is (the old dimension + number of wolffd@0: % different classes). In each vector, one of the new components has wolffd@0: % value '1' (this depends on the class of the vector), and others '0'. wolffd@0: % Calls SOM_MAKE to construct the map. Then the class of each map unit wolffd@0: % is determined by taking maximum over these added components, and a wolffd@0: % label is give accordingly. Finally, the extra components (the wolffd@0: % 1-of-N -coded ones) are removed. wolffd@0: % wolffd@0: % REFERENCES wolffd@0: % wolffd@0: % Kohonen, T., "Self-Organizing Map", 2nd ed., Springer-Verlag, wolffd@0: % Berlin, 1995, pp. 160-161. wolffd@0: % Kohonen, T., Mäkivasara, K., Saramäki, T., "Phonetic Maps - wolffd@0: % Insightful Representation of Phonological Features For wolffd@0: % Speech Recognition", In proceedings of International wolffd@0: % Conference on Pattern Recognition (ICPR), Montreal, Canada, wolffd@0: % 1984, pp. 182-185. wolffd@0: % wolffd@0: % REQUIRED INPUT ARGUMENTS wolffd@0: % wolffd@0: % sData The data to use in the training. wolffd@0: % (struct) A data struct. '.comp_names' as well as '.name' wolffd@0: % is copied to the map. The class information is wolffd@0: % taken from the first column of '.labels' field. wolffd@0: % wolffd@0: % OPTIONAL INPUT ARGUMENTS wolffd@0: % wolffd@0: % argID (string) Argument identifier string (see below). wolffd@0: % value (varies) Value for the argument (see below). wolffd@0: % wolffd@0: % The optional arguments can be given as 'argID',value -pairs. If an wolffd@0: % argument is given value multiple times, the last one is used. wolffd@0: % Here are the argument IDs and corresponding values: wolffd@0: % 'munits' (scalar) the preferred number of map units - this may wolffd@0: % change a bit, depending on the properties of the data wolffd@0: % 'msize' (vector) map grid size wolffd@0: % 'mask' (vector) BMU search mask, size dim x 1 wolffd@0: % 'name' (string) map name wolffd@0: % 'comp_names' (string array / cellstr) component names, size dim x 1 wolffd@0: % 'tracking' (scalar) how much to report, default = 1. This parameter wolffd@0: % is also passed to the training functions. wolffd@0: % The following values are unambiguous and can therefore wolffd@0: % be given without the preceeding argument ID: wolffd@0: % 'algorithm' (string) training algorithm: 'seq' or 'batch' (default) wolffd@0: % 'mapsize' (string) do you want a 'small', 'normal' or 'big' map wolffd@0: % Any explicit settings of munits or msize (or topol) wolffd@0: % override this. wolffd@0: % 'topol' (struct) topology struct wolffd@0: % 'som_topol','sTopol' = 'topol' wolffd@0: % 'lattice' (string) map lattice, 'hexa' or 'rect' wolffd@0: % 'shape' (string) map shape, 'sheet', 'cyl' or 'toroid' wolffd@0: % 'neigh' (string) neighborhood function, 'gaussian', 'cutgauss', wolffd@0: % 'ep' or 'bubble' wolffd@0: % wolffd@0: % OUTPUT ARGUMENTS wolffd@0: % wolffd@0: % sMap (struct) SOM -map struct wolffd@0: % wolffd@0: % EXAMPLES wolffd@0: % wolffd@0: % To simply train a map with default parameters: wolffd@0: % wolffd@0: % sMap = som_supervised(sData); wolffd@0: % wolffd@0: % With the optional arguments, the initialization and training can be wolffd@0: % influenced. To change map size, use 'msize', 'munits' or 'mapsize' wolffd@0: % arguments: wolffd@0: % wolffd@0: % sMap = som_supervised(D,'mapsize','big'); or wolffd@0: % sMap = som_supervised(D,'big'); wolffd@0: % sMap = som_supervised(D,'munits', 100); wolffd@0: % sMap = som_supervised(D,'msize', [20 10]); wolffd@0: % wolffd@0: % Argument 'algorithm' can be used to switch between 'seq' and 'batch' wolffd@0: % algorithms. 'batch' is the default, so to use 'seq' algorithm: wolffd@0: % wolffd@0: % sMap = som_supervised(D,'algorithm','seq'); or wolffd@0: % sMap = som_supervised(D,'seq'); wolffd@0: % wolffd@0: % The 'tracking' argument can be used to control the amout of reporting wolffd@0: % during training. The argument is used in this function, and it is wolffd@0: % passed to the training functions. To make the function work silently wolffd@0: % set it to 0. wolffd@0: % wolffd@0: % sMap = som_supervised(D,'tracking',0); wolffd@0: % wolffd@0: % SEE ALSO wolffd@0: % wolffd@0: % som_make Create, initialize and train Self-Organizing map. wolffd@0: % som_autolabel Label SOM/data set based on another SOM/data set. wolffd@0: wolffd@0: % Contributed to SOM Toolbox vs2, Feb 2nd, 2000 by Juha Parhankangas wolffd@0: % Copyright (c) by Juha Parhankangas wolffd@0: % http://www.cis.hut.fi/projects/somtoolbox/ wolffd@0: wolffd@0: % Juha Parhankangas 050100 wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: D0 = sData.data; wolffd@0: [c,n,classlabels] = class2num(sData.labels(:,1)); wolffd@0: wolffd@0: %%%%%%%% Checking arguments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: if ~isstruct(sData) wolffd@0: error('Argument ''sData'' must be a ''som_data'' -struct.'); wolffd@0: else wolffd@0: data_name = sData.name; wolffd@0: comp_names = sData.comp_names; wolffd@0: comp_norm = sData.comp_norm; wolffd@0: end wolffd@0: wolffd@0: [dlen,dim] = size(sData.data); wolffd@0: wolffd@0: % defaults wolffd@0: wolffd@0: mapsize = ''; wolffd@0: sM = som_map_struct(dim+n); wolffd@0: sTopol = sM.topol; wolffd@0: munits = prod(sTopol.msize); % should be zero wolffd@0: mask = sM.mask; wolffd@0: name = sM.name; wolffd@0: neigh = sM.neigh; wolffd@0: tracking = 1; wolffd@0: algorithm = 'batch'; wolffd@0: wolffd@0: %%%% changes to defaults (checking varargin) %%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: i=1; wolffd@0: while i <= length(varargin) wolffd@0: argok = 1; wolffd@0: if ischar(varargin{i}) wolffd@0: switch varargin{i}, wolffd@0: % argument IDs wolffd@0: case 'mask', wolffd@0: i=i+1; wolffd@0: mask = varargin{i}; wolffd@0: case 'munits', wolffd@0: i=i+1; wolffd@0: munits = varargin{i}; wolffd@0: case 'msize', wolffd@0: i=i+1; wolffd@0: sTopol.msize = varargin{i}; wolffd@0: munits = prod(sTopol.msize); wolffd@0: case 'mapsize', wolffd@0: i=i+1; wolffd@0: mapsize = varargin{i}; wolffd@0: case 'name', wolffd@0: i=i+1; wolffd@0: name = varargin{i}; wolffd@0: case 'comp_names', wolffd@0: i=i+1; wolffd@0: comp_names = varargin{i}; wolffd@0: case 'lattice', wolffd@0: i=i+1; wolffd@0: sTopol.lattice = varargin{i}; wolffd@0: case 'shape', wolffd@0: i=i+1; wolffd@0: sTopol.shape = varargin{i}; wolffd@0: case {'topol','som_topol','sTopol'}, wolffd@0: i=i+1; wolffd@0: sTopol = varargin{i}; wolffd@0: munits = prod(sTopol.msize); wolffd@0: case 'neigh', wolffd@0: i=i+1; wolffd@0: neigh = varargin{i}; wolffd@0: case 'tracking', wolffd@0: i=i+1; wolffd@0: tracking = varargin{i}; wolffd@0: case 'algorithm', wolffd@0: i=i+1; wolffd@0: algorithm = varargin{i}; wolffd@0: % unambiguous values wolffd@0: case {'hexa','rect'}, wolffd@0: sTopol.lattice = varargin{i}; wolffd@0: case {'sheet','cyl','toroid'}, wolffd@0: sTopol.shape = varargin{i}; wolffd@0: case {'gaussian','cutgauss','ep','bubble'}, wolffd@0: neigh = varargin{i}; wolffd@0: case {'seq','batch'}, wolffd@0: algorithm = varargin{i}; wolffd@0: case {'small','normal','big'}, wolffd@0: mapsize = varargin{i}; wolffd@0: otherwise argok=0; wolffd@0: end wolffd@0: elseif isstruct(varargin{i}) & isfield(varargin{i},'type'), wolffd@0: switch varargin{i}(1).type, wolffd@0: case 'som_topol', wolffd@0: sTopol = varargin{i}; wolffd@0: otherwise argok=0; wolffd@0: end wolffd@0: else wolffd@0: argok = 0; wolffd@0: end wolffd@0: if ~argok, wolffd@0: disp(['(som_supervised) Ignoring invalid argument #' num2str(i+1)]); wolffd@0: end wolffd@0: i = i+1; wolffd@0: end wolffd@0: wolffd@0: %%%%%%%% Action %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: wolffd@0: wolffd@0: % constructing the training data by adding 1-of-N -coded matrix to the wolffd@0: % original data. wolffd@0: wolffd@0: [dlen,dim] = size(D0); wolffd@0: wolffd@0: Dc = zeros(dlen,n); wolffd@0: wolffd@0: for i=1:dlen wolffd@0: if c(i) wolffd@0: Dc(i,c(i)) = 1; wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: D = [D0, Dc]; wolffd@0: wolffd@0: % initialization and training wolffd@0: wolffd@0: sD = som_data_struct(D,... wolffd@0: 'name',data_name); wolffd@0: wolffd@0: sM = som_make(sD,... wolffd@0: 'mask',mask,... wolffd@0: 'munits',munits,... wolffd@0: 'name',data_name,... wolffd@0: 'tracking',tracking,... wolffd@0: 'algorithm',algorithm,... wolffd@0: 'mapsize',mapsize,... wolffd@0: 'topol',sTopol,... wolffd@0: 'neigh',neigh); wolffd@0: wolffd@0: % add labels wolffd@0: wolffd@0: for i=1:prod(sM.topol.msize), wolffd@0: [dummy,class] = max(sM.codebook(i,dim+[1:n])); wolffd@0: sM.labels{i} = classlabels{class}; wolffd@0: end wolffd@0: wolffd@0: %sD.labels = sData.labels; wolffd@0: %sM = som_autolabel(sM,sD,'vote'); wolffd@0: wolffd@0: % remove extra components and modify map -struct wolffd@0: wolffd@0: sM.codebook = sM.codebook(:,1:dim); wolffd@0: sM.mask = sM.mask(1:dim); wolffd@0: sM.comp_names = sData.comp_names; wolffd@0: sM.comp_norm = sData.comp_norm; wolffd@0: wolffd@0: % remove extras from sM.trainhist wolffd@0: wolffd@0: for i=1:length(sM.trainhist) wolffd@0: if sM.trainhist(i).mask wolffd@0: sM.trainhist(i).mask = sM.trainhist(i).mask(1:dim); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: function [numbers, n, names] = class2num(class) wolffd@0: wolffd@0: names = {}; wolffd@0: numbers = zeros(length(class),1); wolffd@0: wolffd@0: for i=1:length(class) wolffd@0: if ~isempty(class{i}) & ~any(strcmp(class{i},names)) wolffd@0: names=cat(1,names,class(i)); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: n=length(names); wolffd@0: wolffd@0: tmp_numbers = (1:n)'; wolffd@0: wolffd@0: for i=1:length(class) wolffd@0: if ~isempty(class{i}) wolffd@0: numbers(i,1) = find(strcmp(class{i},names)); wolffd@0: end wolffd@0: end