Mercurial > hg > camir-aes2014
diff toolboxes/MIRtoolbox1.3.2/somtoolbox/som_distortion.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/som_distortion.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,138 @@ +function [adm,admu,tdmu] = som_distortion(sM, D, arg1, arg2) + +%SOM_DISTORTION Calculate distortion measure for the map. +% +% [adm,admu,tdmu] = som_distortion(sMap, D, [radius], ['prob']) +% +% adm = som_distortion(sMap,D); +% [adm,admu] = som_distortion(sMap,D); +% som_show(sMap,'color',admu); +% +% Input and output arguments: +% sMap (struct) a map struct +% D (struct) a data struct +% (matrix) size dlen x dim, a data matrix +% [radius] (scalar) neighborhood function radius to be used. +% Defaults to the last radius_fin in the +% trainhist field of the map struct, or 1 if +% that is missing. +% ['prob'] (string) If given, this argument forces the +% neigborhood function values for each map +% unit to be normalized so that they sum to 1. +% +% adm (scalar) average distortion measure (sum(dm)/dlen) +% admu (vector) size munits x 1, average distortion in each unit +% tdmu (vector) size munits x 1, total distortion for each unit +% +% The distortion measure is defined as: +% 2 +% E = sum sum h(bmu(i),j) ||m(j) - x(i)|| +% i j +% +% where m(i) is the ith prototype vector of SOM, x(j) is the jth data +% vector, and h(.,.) is the neighborhood function. In case of fixed +% neighborhood and discreet data, the distortion measure can be +% interpreted as the energy function of the SOM. Note, though, that +% the learning rule that follows from the distortion measure is +% different from the SOM training rule, so SOM only minimizes the +% distortion measure approximately. +% +% If the 'prob' argument is given, the distortion measure can be +% interpreted as an expected quantization error when the neighborhood +% function values give the likelyhoods of accidentally assigning +% vector j to unit i. The normal quantization error is a special case +% of this with zero incorrect assignement likelihood. +% +% NOTE: when calculating BMUs and distances, the mask of the given +% map is used. +% +% See also SOM_QUALITY, SOM_BMUS, SOM_HITS. + +% Reference: Kohonen, T., "Self-Organizing Map", 2nd ed., +% Springer-Verlag, Berlin, 1995, pp. 120-121. +% +% Graepel, T., Burger, M. and Obermayer, K., +% "Phase Transitions in Stochastic Self-Organizing Maps", +% Physical Review E, Vol 56, No 4, pp. 3876-3890 (1997). + +% Contributed to SOM Toolbox vs2, Feb 3rd, 2000 by Juha Vesanto +% Copyright (c) by Juha Vesanto +% http://www.cis.hut.fi/projects/somtoolbox/ + +% Version 2.0beta juuso 030200 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% check arguments + +% input arguments +if nargin < 2, error('Not enough input arguments.'); end + +% map +M = sM.codebook; +munits = prod(sM.topol.msize); + +% data +if isstruct(D), D = D.data; end +[dlen dim] = size(D); + +% arg1, arg2 +rad = NaN; +normalize = 0; +if nargin>2, + if isnumeric(arg1), rad = arg1; + elseif ischar(arg1) & strcmp(arg1,'prob'), normalize = 0; + end +end +if nargin>3, + if isnumeric(arg2), rad = arg2; + elseif ischar(arg2) & strcmp(arg2,'prob'), normalize = 0; + end +end + +% neighborhood radius +if isempty(rad) | isnan(rad), + if ~isempty(sM.trainhist), rad = sM.trainhist(end).radius_fin; + else rad = 1; + end +end +if rad<eps, rad = eps; end + +% neighborhood +Ud = som_unit_dists(sM.topol); +switch sM.neigh, + case 'bubble', H = (Ud <= rad); + case 'gaussian', H = exp(-(Ud.^2)/(2*rad*rad)); + case 'cutgauss', H = exp(-(Ud.^2)/(2*rad*rad)) .* (Ud <= rad); + case 'ep', H = (1 - (Ud.^2)/rad) .* (Ud <= rad); +end +if normalize, + for i=1:munits, H(:,i) = H(:,i)/sum(H(:,i)); end +end + +% total distortion measure +mu_x_1 = ones(munits,1); +tdmu = zeros(munits,1); +hits = zeros(munits,1); +for i=1:dlen, + x = D(i,:); % data sample + known = ~isnan(x); % its known components + Dx = M(:,known) - x(mu_x_1,known); % each map unit minus the vector + dist2 = (Dx.^2)*sM.mask(known); % squared distances + [qerr bmu] = min(dist2); % find BMU + tdmu = tdmu + dist2.*H(:,bmu); % add to distortion measure + hits(bmu) = hits(bmu)+1; % add to hits +end + +% average distortion per unit +admu = tdmu; +ind = find(hits>0); +admu(ind) = admu(ind) ./ hits(ind); + +% average distortion measure +adm = sum(tdmu)/dlen; + +return; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +