diff toolboxes/MIRtoolbox1.3.2/somtoolbox/lvq3.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolboxes/MIRtoolbox1.3.2/somtoolbox/lvq3.m	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,215 @@
+function codebook = lvq3(codebook,data,rlen,alpha,win,epsilon)
+
+%LVQ3 trains codebook with LVQ3 -algorithm
+%
+% sM = lvq3(sM,D,rlen,alpha,win,epsilon)
+%
+%   sM = lvq3(sM,sD,50*length(sM.codebook),0.05,0.2,0.3);
+%
+%  Input and output arguments: 
+%   sM      (struct) map struct, the class information must be 
+%                    present on the first column of .labels field
+%   D       (struct) data struct, the class information must
+%                    be present on the first column of .labels field
+%   rlen    (scalar) running length
+%   alpha   (scalar) learning parameter, e.g. 0.05
+%   win     (scalar) window width parameter, e.g. 0.25
+%   epsilon (scalar) relative learning parameter, e.g. 0.3
+%
+%   sM      (struct) map struct, the trained codebook
+%
+% NOTE: does not take mask into account.
+%
+% For more help, try 'type lvq3', or check out online documentation.
+% See also LVQ1, SOM_SUPERVISED, SOM_SEQTRAIN.
+
+%%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% lvq3
+%
+% PURPOSE
+%
+% Trains codebook with the LVQ3 -algorithm (described below).
+%
+% SYNTAX
+%
+% sM = lvq3(sM, data, rlen, alpha, win, epsilon)
+%
+% DESCRIPTION
+%
+% Trains codebook with the LVQ3 -algorithm. Codebook contains a number
+% of vectors (mi, i=1,2,...,n) and so does data (vectors xj, j=1,2,...k).
+% Both vector sets are classified: vectors may have a class (classes are
+% set to data- or map -structure's 'labels' -field. For each xj the two 
+% closest codebookvectors mc1 and mc2 are searched (euclidean distances
+% d1 and d2). xj must fall into the zone of window. That happens if:
+%
+%    min(d1/d2, d2/d1) > s, where s = (1-win) / (1+win).
+%
+% If xj belongs to the same class of one of the mc1 and mc1, codebook
+% is updated as follows (let mc1 belong to the same class as xj):
+%    mc1(t+1) = mc1(t) + alpha * (xj(t) - mc1(t))
+%    mc2(t+1) = mc2(t) - alpha * (xj(t) - mc2(t))
+% If both mc1 and mc2 belong to the same class as xj, codebook is
+% updated as follows:
+%    mc1(t+1) = mc1(t) + epsilon * alpha * (xj(t) - mc1(t))
+%    mc2(t+1) = mc2(t) + epsilon * alpha * (xj(t) - mc2(t))
+% Otherwise updating is not performed.
+%
+% Argument 'rlen' tells how many times training -sequence is performed.
+%
+% Argument 'alpha' is recommended to be smaller than 0.1 and argument
+% 'epsilon' should be between 0.1 and 0.5.
+%
+% NOTE: does not take mask into account.
+%
+% REFERENCES
+%
+% Kohonen, T., "Self-Organizing Map", 2nd ed., Springer-Verlag, 
+%    Berlin, 1995, pp. 181-182.
+%
+% See also LVQ_PAK from http://www.cis.hut.fi/research/som_lvq_pak.shtml
+% 
+% REQUIRED INPUT ARGUMENTS
+%
+%  sM                The data to be trained.
+%          (struct)  A map struct.
+%
+%  data              The data to use in training.
+%          (struct)  A data struct.
+%
+%  rlen    (integer) Running length of LVQ3 -algorithm.
+%                    
+%  alpha   (float)   Learning rate used in training, e.g. 0.05
+%
+%  win     (float)   Window length, e.g. 0.25
+%  
+%  epsilon (float)   Relative learning parameter, e.g. 0.3
+%
+% OUTPUT ARGUMENTS
+%
+%  sM          Trained data.
+%          (struct)  A map struct.
+%
+% EXAMPLE
+%
+%   lab = unique(sD.labels(:,1));         % different classes
+%   mu = length(lab)*5;                   % 5 prototypes for each    
+%   sM = som_randinit(sD,'msize',[mu 1]); % initial prototypes
+%   sM.labels = [lab;lab;lab;lab;lab];    % their classes
+%   sM = lvq1(sM,sD,50*mu,0.05);          % use LVQ1 to adjust
+%                                         % the prototypes      
+%   sM = lvq3(sM,sD,50*mu,0.05,0.2,0.3);  % then use LVQ3 
+% 
+% SEE ALSO
+% 
+%  lvq1             Use LVQ1 algorithm for training.
+%  som_supervised   Train SOM using supervised training.
+%  som_seqtrain     Train SOM with sequential algorithm.
+
+% Contributed to SOM Toolbox vs2, February 2nd, 2000 by Juha Parhankangas
+% Copyright (c) by Juha Parhankangas
+% http://www.cis.hut.fi/projects/somtoolbox/
+
+% Juha Parhankangas 310100 juuso 020200
+
+NOTFOUND = 1;
+
+cod = codebook.codebook;
+dat = data.data;
+
+c_class = codebook.labels(:,1);
+d_class = data.labels(:,1);
+
+s = (1-win)/(1+win);
+
+x = size(dat,1);
+y = size(cod,2);
+
+c_class=class2num(c_class);
+d_class=class2num(d_class);
+
+ONES=ones(size(cod,1),1);
+
+for t=1:rlen
+  fprintf('\rTraining round: %d/%d',t,rlen);
+  tmp = NaN*ones(x,y);
+ 
+  for j=1:x
+    flag = 0;
+    mj = 0;
+    mi = 0;
+    no_NaN=find(~isnan(dat(j,:)));
+    di=sqrt(sum([cod(:,no_NaN) - ONES*dat(j,no_NaN)].^2,2));
+    [foo, ind1] = min(di);
+    di(ind1)=Inf;
+    [foo,ind2] =  min(di);    
+  
+    %ind2=ind2+1;
+
+    if d_class(j) & d_class(j)==c_class(ind1)
+      mj = ind1;
+      mi = ind2;
+      if d_class(j)==c_class(ind2)
+        flag = 1;
+      end
+    elseif d_class(j) & d_class(j)==c_class(ind2)
+      mj = ind2;
+      mi = ind1;
+      if d_class(j)==c_class(ind1)
+        flag = 1;
+      end
+    end
+
+    if mj & mi
+      if flag
+        tmp([mj mi],:) = cod([mj mi],:) + epsilon*alpha*...
+                       (dat([j j],:) - cod([mj mi],:));
+      else
+        tmp(mj,:) = cod(mj,:) + alpha * (dat(j,:)-cod(mj,:));
+        tmp(mi,:) = cod(mi,:) - alpha * (dat(j,:)-cod(mj,:));
+      end
+    end  
+  end    
+  inds = find(~isnan(sum(tmp,2)));
+  cod(inds,:) = tmp(inds,:);
+end
+fprintf(1,'\n');
+
+sTrain = som_set('som_train','algorithm','lvq3',...
+		 'data_name',data.name,...
+		 'neigh','',...
+		 'mask',ones(y,1),...
+		 'radius_ini',NaN,...
+		 'radius_fin',NaN,...
+		 'alpha_ini',alpha,...
+		 'alpha_type','constant',...
+		 'trainlen',rlen,...
+		 'time',datestr(now,0));
+codebook.trainhist(end+1) = sTrain;
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+function nos = class2num(class)
+
+names = {};
+nos = zeros(length(class),1);
+
+for i=1:length(class)
+  if ~isempty(class{i}) & ~any(strcmp(class{i},names))
+    names=cat(1,names,class(i));
+  end
+end
+
+tmp_nos = (1:length(names))';
+
+for i=1:length(class)
+  if ~isempty(class{i})
+    nos(i,1) = find(strcmp(class{i},names));    
+  end
+end
+
+
+
+
+