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