wolffd@0
|
1 function [hits] = som_hits(sMap, sData, mode)
|
wolffd@0
|
2
|
wolffd@0
|
3 %SOM_HITS Calculate the response of the given data on the map.
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % hits = som_hits(sMap, sData, [mode])
|
wolffd@0
|
6 %
|
wolffd@0
|
7 % h = som_hits(sMap,sData);
|
wolffd@0
|
8 % h = som_hits(sMap,sData,'fuzzy');
|
wolffd@0
|
9 %
|
wolffd@0
|
10 % Input and output arguments ([]'s are optional):
|
wolffd@0
|
11 % sMap (struct) map struct
|
wolffd@0
|
12 % (matrix) codebook matrix, size munits x dim
|
wolffd@0
|
13 % sData (struct) data struct
|
wolffd@0
|
14 % (matrix) data matrix, size dlen x dim
|
wolffd@0
|
15 % [mode] (string) 'crisp' (default), 'kernel', 'fuzzy'
|
wolffd@0
|
16 %
|
wolffd@0
|
17 % hits (vector) the number of hits in each map unit, length = munits
|
wolffd@0
|
18 %
|
wolffd@0
|
19 % The response of the data on the map can be calculated e.g. in
|
wolffd@0
|
20 % three ways, selected with the mode argument:
|
wolffd@0
|
21 % 'crisp' traditional hit histogram
|
wolffd@0
|
22 % 'kernel' a sum of dlen neighborhood kernels, where kernel
|
wolffd@0
|
23 % is positioned on the BMU of each data sample. The
|
wolffd@0
|
24 % neighborhood function is sMap.neigh and the
|
wolffd@0
|
25 % neighborhood width is sMap.trainhist(end).radius_fin
|
wolffd@0
|
26 % or 1 if this is empty or NaN
|
wolffd@0
|
27 % 'fuzzy' fuzzy response calculated by summing 1./(1+(q/a)^2)
|
wolffd@0
|
28 % for each data sample, where q is a vector containing
|
wolffd@0
|
29 % distance from the data sample to each map unit and
|
wolffd@0
|
30 % a is average quantization error
|
wolffd@0
|
31 %
|
wolffd@0
|
32 % For more help, try 'type som_hits' or check out online documentation.
|
wolffd@0
|
33 % See also SOM_AUTOLABEL, SOM_BMUS.
|
wolffd@0
|
34
|
wolffd@0
|
35 %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
36 %
|
wolffd@0
|
37 % som_hits
|
wolffd@0
|
38 %
|
wolffd@0
|
39 % PURPOSE
|
wolffd@0
|
40 %
|
wolffd@0
|
41 % Calculate the response of the given data on the map.
|
wolffd@0
|
42 %
|
wolffd@0
|
43 % SYNTAX
|
wolffd@0
|
44 %
|
wolffd@0
|
45 % hits = som_hits(sMap, sData)
|
wolffd@0
|
46 % hits = som_hits(M, D)
|
wolffd@0
|
47 % hits = som_hits(..., mode)
|
wolffd@0
|
48 %
|
wolffd@0
|
49 % DESCRIPTION
|
wolffd@0
|
50 %
|
wolffd@0
|
51 % Returns a vector indicating the response of the map to the data.
|
wolffd@0
|
52 % The response of the data on the map can be calculated e.g. in
|
wolffd@0
|
53 % three ways, selected with the mode argument:
|
wolffd@0
|
54 % 'crisp' traditional hit histogram: how many times each map unit
|
wolffd@0
|
55 % was the BMU for the data set
|
wolffd@0
|
56 % 'kernel' a sum of neighborhood kernels, where a kernel
|
wolffd@0
|
57 % is positioned on the BMU of each data sample. The
|
wolffd@0
|
58 % neighborhood function is sMap.neigh and the
|
wolffd@0
|
59 % neighborhood width is sMap.trainhist(end).radius_fin
|
wolffd@0
|
60 % or 1 if this is not available
|
wolffd@0
|
61 % 'fuzzy' fuzzy response calculated by summing
|
wolffd@0
|
62 %
|
wolffd@0
|
63 % 1
|
wolffd@0
|
64 % ------------
|
wolffd@0
|
65 % 1 + (q/a)^2
|
wolffd@0
|
66 %
|
wolffd@0
|
67 % for each data sample, where q is a vector containing
|
wolffd@0
|
68 % distance from the data sample to each map unit and
|
wolffd@0
|
69 % a is average quantization error
|
wolffd@0
|
70 %
|
wolffd@0
|
71 % REQUIRED INPUT ARGUMENTS
|
wolffd@0
|
72 %
|
wolffd@0
|
73 % sMap The vectors from among which the BMUs are searched
|
wolffd@0
|
74 % for. These must not have any unknown components (NaNs).
|
wolffd@0
|
75 % (struct) map struct
|
wolffd@0
|
76 % (matrix) codebook matrix, size munits x dim
|
wolffd@0
|
77 %
|
wolffd@0
|
78 % sData The data vector(s) for which the BMUs are searched.
|
wolffd@0
|
79 % (struct) data struct
|
wolffd@0
|
80 % (matrix) data matrix, size dlen x dim
|
wolffd@0
|
81 %
|
wolffd@0
|
82 % OPTIONAL INPUT ARGUMENTS
|
wolffd@0
|
83 %
|
wolffd@0
|
84 % mode (string) The respond mode: 'crisp' (default), 'kernel'
|
wolffd@0
|
85 % or 'fuzzy'. 'kernel' can only be used if
|
wolffd@0
|
86 % the first argument (sMap) is a map struct.
|
wolffd@0
|
87 %
|
wolffd@0
|
88 % OUTPUT ARGUMENTS
|
wolffd@0
|
89 %
|
wolffd@0
|
90 % hits (vector) The number of hits in each map unit.
|
wolffd@0
|
91 %
|
wolffd@0
|
92 % EXAMPLES
|
wolffd@0
|
93 %
|
wolffd@0
|
94 % hits = som_hits(sM,D);
|
wolffd@0
|
95 % hits = som_hits(sM,D,'kernel');
|
wolffd@0
|
96 % hits = som_hits(sM,D,'fuzzy');
|
wolffd@0
|
97 %
|
wolffd@0
|
98 % SEE ALSO
|
wolffd@0
|
99 %
|
wolffd@0
|
100 % som_bmus Find BMUs and quantization errors for a given data set.
|
wolffd@0
|
101
|
wolffd@0
|
102 % Copyright (c) 1997-2000 by the SOM toolbox programming team.
|
wolffd@0
|
103 % http://www.cis.hut.fi/projects/somtoolbox/
|
wolffd@0
|
104
|
wolffd@0
|
105 % Version 1.0beta juuso 220997
|
wolffd@0
|
106 % Version 2.0beta juuso 161199
|
wolffd@0
|
107
|
wolffd@0
|
108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
109 %% check arguments
|
wolffd@0
|
110
|
wolffd@0
|
111 error(nargchk(2, 3, nargin)); % check no. of input args is correct
|
wolffd@0
|
112
|
wolffd@0
|
113 if isstruct(sMap),
|
wolffd@0
|
114 switch sMap.type,
|
wolffd@0
|
115 case 'som_map', munits = prod(sMap.topol.msize);
|
wolffd@0
|
116 case 'som_data', munits = size(sMap.data,1);
|
wolffd@0
|
117 otherwise,
|
wolffd@0
|
118 error('Illegal struct for 1st argument.')
|
wolffd@0
|
119 end
|
wolffd@0
|
120 else
|
wolffd@0
|
121 munits = size(sMap,1);
|
wolffd@0
|
122 end
|
wolffd@0
|
123 hits = zeros(munits,1);
|
wolffd@0
|
124
|
wolffd@0
|
125 if nargin<3, mode = 'crisp'; end
|
wolffd@0
|
126
|
wolffd@0
|
127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
128 %% action
|
wolffd@0
|
129
|
wolffd@0
|
130 % calculate BMUs
|
wolffd@0
|
131 [bmus,qerrs] = som_bmus(sMap,sData,1);
|
wolffd@0
|
132
|
wolffd@0
|
133 switch mode,
|
wolffd@0
|
134 case 'crisp',
|
wolffd@0
|
135
|
wolffd@0
|
136 % for each unit, check how many hits it got
|
wolffd@0
|
137 for i=1:munits, hits(i) = sum(bmus == i); end
|
wolffd@0
|
138
|
wolffd@0
|
139 case 'kernel',
|
wolffd@0
|
140
|
wolffd@0
|
141 % check that sMap really is a map
|
wolffd@0
|
142 if ~isstruct(sMap) & ~strcmp(sMap.type,'som_map'),
|
wolffd@0
|
143 error('Kernel mode can only be used for maps.');
|
wolffd@0
|
144 end
|
wolffd@0
|
145
|
wolffd@0
|
146 % calculate neighborhood kernel
|
wolffd@0
|
147 Ud = som_unit_dists(sMap.topol).^2;
|
wolffd@0
|
148 sTrain = sMap.trainhist(end);
|
wolffd@0
|
149 if ~isempty(sTrain),
|
wolffd@0
|
150 rad = sTrain.radius_fin;
|
wolffd@0
|
151 if isempty(rad) | isnan(rad), rad = 1; end
|
wolffd@0
|
152 else
|
wolffd@0
|
153 rad = 1;
|
wolffd@0
|
154 end
|
wolffd@0
|
155 rad = rad^2;
|
wolffd@0
|
156 if rad==0, rad = eps; end % to avoid divide-by-0 errors
|
wolffd@0
|
157 switch sTrain.neigh,
|
wolffd@0
|
158 case 'bubble', H = (Ud<=rad);
|
wolffd@0
|
159 case 'gaussian', H = exp(-Ud/(2*rad));
|
wolffd@0
|
160 case 'cutgauss', H = exp(-Ud/(2*rad)) .* (Ud<=rad);
|
wolffd@0
|
161 case 'ep', H = (1-Ud/rad) .* (Ud<=rad);
|
wolffd@0
|
162 end
|
wolffd@0
|
163
|
wolffd@0
|
164 % weight hits with neighborhood kernel
|
wolffd@0
|
165 hits = sum(H(bmus,:),1)';
|
wolffd@0
|
166
|
wolffd@0
|
167 case 'fuzzy',
|
wolffd@0
|
168
|
wolffd@0
|
169 % extract the two matrices (M, D) and the mask
|
wolffd@0
|
170 mask = [];
|
wolffd@0
|
171 if isstruct(sMap),
|
wolffd@0
|
172 if strcmp(sMap.type,'som_data'), M = sMap.data;
|
wolffd@0
|
173 else M = sMap.codebook; mask = sMap.mask;
|
wolffd@0
|
174 end
|
wolffd@0
|
175 else M = sMap;
|
wolffd@0
|
176 end
|
wolffd@0
|
177 if any(isnan(M(:))),
|
wolffd@0
|
178 error('Data in first argument must not have any NaNs.');
|
wolffd@0
|
179 end
|
wolffd@0
|
180
|
wolffd@0
|
181 if isstruct(sData),
|
wolffd@0
|
182 switch sData.type,
|
wolffd@0
|
183 case 'som_map',
|
wolffd@0
|
184 D = sData.codebook;
|
wolffd@0
|
185 if isempty(mask), mask = sData.mask; end
|
wolffd@0
|
186 case 'som_data', D = sData.data;
|
wolffd@0
|
187 otherwise, error('Illegal 2nd argument.');
|
wolffd@0
|
188 end
|
wolffd@0
|
189 else D = sData;
|
wolffd@0
|
190 end
|
wolffd@0
|
191 [dlen dim] = size(D);
|
wolffd@0
|
192 if isempty(mask), mask = ones(dim,1); end
|
wolffd@0
|
193
|
wolffd@0
|
194 % scaling factor
|
wolffd@0
|
195 a = mean(qerrs).^2;
|
wolffd@0
|
196
|
wolffd@0
|
197 % calculate distances & bmus
|
wolffd@0
|
198 % (this is better explained in som_batchtrain and som_bmus)
|
wolffd@0
|
199 Known = ~isnan(D); D(find(~Known)) = 0; % unknown components
|
wolffd@0
|
200 blen = min(munits,dlen); % block size
|
wolffd@0
|
201 W1 = mask*ones(1,blen); W2 = ones(munits,1)*mask'; D = D'; Known = Known';
|
wolffd@0
|
202 i0 = 0;
|
wolffd@0
|
203 while i0+1<=dlen,
|
wolffd@0
|
204 inds = [(i0+1):min(dlen,i0+blen)]; i0 = i0+blen; % indeces
|
wolffd@0
|
205 Dist = (M.^2)*(W1(:,1:length(inds)).*Known(:,inds)) ...
|
wolffd@0
|
206 + W2*(D(:,inds).^2) ...
|
wolffd@0
|
207 - 2*M*diag(mask)*D(:,inds); % squared distances
|
wolffd@0
|
208 hits = hits + sum(1./(1+Dist/a),2);
|
wolffd@0
|
209 end
|
wolffd@0
|
210
|
wolffd@0
|
211 otherwise,
|
wolffd@0
|
212 error(['Unknown mode: ' mode]);
|
wolffd@0
|
213
|
wolffd@0
|
214 end
|
wolffd@0
|
215
|
wolffd@0
|
216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
217
|