Mercurial > hg > camir-aes2014
diff toolboxes/MIRtoolbox1.3.2/somtoolbox/som_hits.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_hits.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,217 @@ +function [hits] = som_hits(sMap, sData, mode) + +%SOM_HITS Calculate the response of the given data on the map. +% +% hits = som_hits(sMap, sData, [mode]) +% +% h = som_hits(sMap,sData); +% h = som_hits(sMap,sData,'fuzzy'); +% +% Input and output arguments ([]'s are optional): +% sMap (struct) map struct +% (matrix) codebook matrix, size munits x dim +% sData (struct) data struct +% (matrix) data matrix, size dlen x dim +% [mode] (string) 'crisp' (default), 'kernel', 'fuzzy' +% +% hits (vector) the number of hits in each map unit, length = munits +% +% The response of the data on the map can be calculated e.g. in +% three ways, selected with the mode argument: +% 'crisp' traditional hit histogram +% 'kernel' a sum of dlen neighborhood kernels, where kernel +% is positioned on the BMU of each data sample. The +% neighborhood function is sMap.neigh and the +% neighborhood width is sMap.trainhist(end).radius_fin +% or 1 if this is empty or NaN +% 'fuzzy' fuzzy response calculated by summing 1./(1+(q/a)^2) +% for each data sample, where q is a vector containing +% distance from the data sample to each map unit and +% a is average quantization error +% +% For more help, try 'type som_hits' or check out online documentation. +% See also SOM_AUTOLABEL, SOM_BMUS. + +%%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% som_hits +% +% PURPOSE +% +% Calculate the response of the given data on the map. +% +% SYNTAX +% +% hits = som_hits(sMap, sData) +% hits = som_hits(M, D) +% hits = som_hits(..., mode) +% +% DESCRIPTION +% +% Returns a vector indicating the response of the map to the data. +% The response of the data on the map can be calculated e.g. in +% three ways, selected with the mode argument: +% 'crisp' traditional hit histogram: how many times each map unit +% was the BMU for the data set +% 'kernel' a sum of neighborhood kernels, where a kernel +% is positioned on the BMU of each data sample. The +% neighborhood function is sMap.neigh and the +% neighborhood width is sMap.trainhist(end).radius_fin +% or 1 if this is not available +% 'fuzzy' fuzzy response calculated by summing +% +% 1 +% ------------ +% 1 + (q/a)^2 +% +% for each data sample, where q is a vector containing +% distance from the data sample to each map unit and +% a is average quantization error +% +% REQUIRED INPUT ARGUMENTS +% +% sMap The vectors from among which the BMUs are searched +% for. These must not have any unknown components (NaNs). +% (struct) map struct +% (matrix) codebook matrix, size munits x dim +% +% sData The data vector(s) for which the BMUs are searched. +% (struct) data struct +% (matrix) data matrix, size dlen x dim +% +% OPTIONAL INPUT ARGUMENTS +% +% mode (string) The respond mode: 'crisp' (default), 'kernel' +% or 'fuzzy'. 'kernel' can only be used if +% the first argument (sMap) is a map struct. +% +% OUTPUT ARGUMENTS +% +% hits (vector) The number of hits in each map unit. +% +% EXAMPLES +% +% hits = som_hits(sM,D); +% hits = som_hits(sM,D,'kernel'); +% hits = som_hits(sM,D,'fuzzy'); +% +% SEE ALSO +% +% som_bmus Find BMUs and quantization errors for a given data set. + +% Copyright (c) 1997-2000 by the SOM toolbox programming team. +% http://www.cis.hut.fi/projects/somtoolbox/ + +% Version 1.0beta juuso 220997 +% Version 2.0beta juuso 161199 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% check arguments + +error(nargchk(2, 3, nargin)); % check no. of input args is correct + +if isstruct(sMap), + switch sMap.type, + case 'som_map', munits = prod(sMap.topol.msize); + case 'som_data', munits = size(sMap.data,1); + otherwise, + error('Illegal struct for 1st argument.') + end +else + munits = size(sMap,1); +end +hits = zeros(munits,1); + +if nargin<3, mode = 'crisp'; end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% action + +% calculate BMUs +[bmus,qerrs] = som_bmus(sMap,sData,1); + +switch mode, +case 'crisp', + + % for each unit, check how many hits it got + for i=1:munits, hits(i) = sum(bmus == i); end + +case 'kernel', + + % check that sMap really is a map + if ~isstruct(sMap) & ~strcmp(sMap.type,'som_map'), + error('Kernel mode can only be used for maps.'); + end + + % calculate neighborhood kernel + Ud = som_unit_dists(sMap.topol).^2; + sTrain = sMap.trainhist(end); + if ~isempty(sTrain), + rad = sTrain.radius_fin; + if isempty(rad) | isnan(rad), rad = 1; end + else + rad = 1; + end + rad = rad^2; + if rad==0, rad = eps; end % to avoid divide-by-0 errors + switch sTrain.neigh, + case 'bubble', H = (Ud<=rad); + case 'gaussian', H = exp(-Ud/(2*rad)); + case 'cutgauss', H = exp(-Ud/(2*rad)) .* (Ud<=rad); + case 'ep', H = (1-Ud/rad) .* (Ud<=rad); + end + + % weight hits with neighborhood kernel + hits = sum(H(bmus,:),1)'; + +case 'fuzzy', + + % extract the two matrices (M, D) and the mask + mask = []; + if isstruct(sMap), + if strcmp(sMap.type,'som_data'), M = sMap.data; + else M = sMap.codebook; mask = sMap.mask; + end + else M = sMap; + end + if any(isnan(M(:))), + error('Data in first argument must not have any NaNs.'); + end + + if isstruct(sData), + switch sData.type, + case 'som_map', + D = sData.codebook; + if isempty(mask), mask = sData.mask; end + case 'som_data', D = sData.data; + otherwise, error('Illegal 2nd argument.'); + end + else D = sData; + end + [dlen dim] = size(D); + if isempty(mask), mask = ones(dim,1); end + + % scaling factor + a = mean(qerrs).^2; + + % calculate distances & bmus + % (this is better explained in som_batchtrain and som_bmus) + Known = ~isnan(D); D(find(~Known)) = 0; % unknown components + blen = min(munits,dlen); % block size + W1 = mask*ones(1,blen); W2 = ones(munits,1)*mask'; D = D'; Known = Known'; + i0 = 0; + while i0+1<=dlen, + inds = [(i0+1):min(dlen,i0+blen)]; i0 = i0+blen; % indeces + Dist = (M.^2)*(W1(:,1:length(inds)).*Known(:,inds)) ... + + W2*(D(:,inds).^2) ... + - 2*M*diag(mask)*D(:,inds); % squared distances + hits = hits + sum(1./(1+Dist/a),2); + end + + otherwise, + error(['Unknown mode: ' mode]); + +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +