wolffd@0: function [color,centroids]=som_kmeanscolor2(mode,sM,C,initRGB,contrast,R) wolffd@0: wolffd@0: % SOM_KMEANSCOLOR2 Color codes a SOM according to averaged or best K-means clustering wolffd@0: % wolffd@0: % color = som_kmeanscolor2('average',sM, C, [initRGB], [contrast],[R]) wolffd@0: % wolffd@0: % color=som_kmeanscolor2('average',sM,[2 4 8 16],som_colorcode(sM,'rgb1'),'enhanced'); wolffd@0: % [color,centroid]=som_kmeanscolor2('best',sM,15,[],'flat',R); wolffd@0: % wolffd@0: % Input and output arguments ([]'s are optional): wolffd@0: % wolffd@0: % mode (string) 'average' or 'best', defalut: 'average' wolffd@0: % sM (struct) a map struct wolffd@0: % C (vector) number of clusters wolffd@0: % [initRGB] (string, matrix) a color code string accepted by SOM_COLORCODE wolffd@0: % or an Mx3 matrix of RGB triples, where M is the number wolffd@0: % of map units. Default: SOM_COLORCODEs default wolffd@0: % [contrast] (string) 'flat', 'enhanced' color contrast mode, default: wolffd@0: % 'enhanced'. wolffd@0: % [R] (scalar) number of K-means trials, default: 30. wolffd@0: % color (matrix) Mx3xC of RGB triples wolffd@0: % centroid (array of matrices) centroid{i} includes codebook for the best wolffd@0: % k-means for C(i) clusters, i.e. the cluster centroids corresponding to wolffd@0: % the color code color(:,:,i). wolffd@0: % wolffd@0: % The function gives a set of color codes for the SOM according to K-means wolffd@0: % clustering. It has two operation modes: wolffd@0: % wolffd@0: % 'average': The idea of coloring is that the color of the units belonging to the same wolffd@0: % cluster is the mean of the original RGB values (see SOM_COLORCODE) of the map units wolffd@0: % belonging to the cluster (see SOM_CLUSTERCOLOR). The K-means clustering is made, wolffd@0: % by default, 30 times and the resulting color codes are averaged for wolffd@0: % each specified number of clusters C(i), i=1,...,k. In a way, the resulting averaged color wolffd@0: % codes reflect the stability of the K-means clustering made on the map units. wolffd@0: % wolffd@0: % 'best': runs the k-means R times for C(i), i=1,...,n clusters as in previous mode, wolffd@0: % but instead of averaging all the R color codes, it picks the one that corresponds to the wolffd@0: % best k-means clustering for each C(i). The 'best' is the one with the lowest wolffd@0: % quantization error. The result may differ from run to run. wolffd@0: % wolffd@0: % EXAMPLE wolffd@0: % wolffd@0: % load iris; % or any other map struct sM wolffd@0: % color=som_kmeanscolor2('average',sM,[2:6]); wolffd@0: % som_show(sM,'umat','all','color',color); wolffd@0: % wolffd@0: % See also SOM_KMEANS, SOM_SHOW, SOM_COLORCODE, SOM_CLUSTERCOLOR, SOM_KMEANSCOLOR wolffd@0: wolffd@0: % Contributed to SOM Toolbox 2.0, 2001 February by Johan Himberg wolffd@0: % Copyright (c) by Johan Himberg wolffd@0: % http://www.cis.hut.fi/projects/somtoolbox/ wolffd@0: wolffd@0: %%% Check number of inputs wolffd@0: wolffd@0: error(nargchk(3, 6, nargin)); % check no. of input args wolffd@0: wolffd@0: %%% Check input args & set defaults wolffd@0: wolffd@0: if ~vis_valuetype(mode,{'string'}), wolffd@0: error('Mode must be a string.'); wolffd@0: end wolffd@0: switch lower(mode), wolffd@0: case{'average','best'} wolffd@0: ; wolffd@0: otherwise wolffd@0: error('Mode must be string ''average'' or ''best''.'); wolffd@0: end wolffd@0: wolffd@0: if isstruct(sM) & isfield(sM,'type') & strcmp(sM.type,'som_map'), wolffd@0: [tmp,lattice,msize]=vis_planeGetArgs(sM); wolffd@0: munits=prod(msize); wolffd@0: if length(msize)>2 wolffd@0: error('Does not work with 3D maps.') wolffd@0: end wolffd@0: else wolffd@0: error('Map struct required for the second input argument!'); wolffd@0: end wolffd@0: wolffd@0: if ~vis_valuetype(C,{'1xn','nx1'}), wolffd@0: error('Vector value expected for cluster number.'); wolffd@0: end wolffd@0: wolffd@0: % Round C and check wolffd@0: C=round(C(:)'); wolffd@0: wolffd@0: if any(C<2), wolffd@0: error('Cluster number must be 2 or more.'); wolffd@0: end wolffd@0: wolffd@0: % check initial color coding wolffd@0: if nargin<4 | isempty(initRGB) wolffd@0: initRGB=som_colorcode(sM); wolffd@0: end wolffd@0: wolffd@0: % check contrast checking wolffd@0: if nargin<5 | isempty(contrast), wolffd@0: contrast='enhanced'; wolffd@0: end wolffd@0: wolffd@0: if ~ischar(contrast), wolffd@0: error('String input expected for input arg. ''contrast''.'); wolffd@0: else wolffd@0: switch lower(contrast) wolffd@0: case {'flat','enhanced'} wolffd@0: ; wolffd@0: otherwise wolffd@0: error(['''flat'' or ''enhanced'' expected for '... wolffd@0: 'input argument ''contrast''.']); wolffd@0: end wolffd@0: end wolffd@0: wolffd@0: if ischar(initRGB), wolffd@0: try wolffd@0: initRGB=som_colorcode(sM,initRGB); wolffd@0: catch wolffd@0: error(['Color code ' initRGB ... wolffd@0: 'was not recognized by SOM_COLORCODE.']); wolffd@0: end wolffd@0: elseif vis_valuetype(initRGB,{'nx3rgb',[munits 3]},'all'), wolffd@0: ; wolffd@0: else wolffd@0: error(['The initial color code must be a string '... wolffd@0: 'or an Mx3 matrix of RGB triples.']); wolffd@0: end wolffd@0: wolffd@0: if nargin<6|isempty(R), wolffd@0: R=30; wolffd@0: end wolffd@0: wolffd@0: if ~vis_valuetype(R,{'1x1'}), wolffd@0: error('''R'' must be scalar.'); wolffd@0: end wolffd@0: wolffd@0: %%% Action %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% wolffd@0: wolffd@0: disp('Wait...'); wolffd@0: index=0; hit_=zeros(munits,munits); wolffd@0: wolffd@0: switch mode, wolffd@0: %% Averaged k-means coloring wolffd@0: case 'average' wolffd@0: for k=C, wolffd@0: disp(['Running K-means for ' num2str(k) ' clusters...']); wolffd@0: color_=zeros(munits,3); wolffd@0: colord_=color_; wolffd@0: % Average R k-means colorings for C clusters wolffd@0: for j=1:R, wolffd@0: [dummy,c]=som_kmeans('batch',sM,k,100,0); % max 100 iterations, verbose off wolffd@0: color_=color_+som_clustercolor(sM,c,initRGB); wolffd@0: end wolffd@0: index=index+1; wolffd@0: color(:,:,index)=color_./R; wolffd@0: end wolffd@0: wolffd@0: %% coloring for 'best' k-means coloring wolffd@0: case 'best' wolffd@0: for k=C, wolffd@0: disp(['Running K-means for ' num2str(k) ' clusters...']); wolffd@0: c=[];err=Inf; div=[]; wolffd@0: %% look for the best k-means among R trials wolffd@0: for i=1:R, wolffd@0: [c_,div_,err_(i)]=som_kmeans('batch',sM,k,100,0); % max 100 iterations, verbose off wolffd@0: if err_(i)