% Labwork#1 - Clustering function lab1 global color color='rgbcm'; % random data generation %x=rand(100,2); %x=spiral([1 1],0.1,0.45,3,0,0.1); %x=spiral2([0 0],0.1,0.5,3,0,0.03); x=spiralmix([1 1],[3 1],0.1,0.45,3,0,0.03); % number of classes K=2; [M,N]=size(x); % M - number of objects in sample, N - number of parameters % classes kernels %c(1:K,1)= ceil((M-1)*rand(1,K)+1); %random kernels %c(1:K,2)= c(1:K,1)+1; %c(1:K,1)=ceil((M-1)*rand(1,K)+1) %random kernels %c(1:K,:)=[1, 2; ceil(M/2+0.5), ceil(M/2+0.5)+1]% explicit kernels c(1:K,1)=[1; ceil(M/2+0.5)];% explicit kernels c(1:K,2)=[2; ceil(M/2+0.5)+1];% explicit kernels %c(1:K,1)=1; len=2*ones(1,K); % current number of objects included in k-th class % plot data for 2-dimensional space figure(1) clf hold on plot(x(:,1),x(:,2),'k.') for i=1:K plot(x(c(i,1),1),x(c(i,1),2),'o','color',color(i)) end pause % clustering data nearest(x,c,len); %===== Subfunctions ================================================== %----- Nearest neigbour clustering ----------------------------------- function nearest(x,c,len) global color [M,N]=size(x); % M - number of objects in sample, N - number of parameters K=length(len); % number of classes % % alpha=0.5; % % distances between each pair of objects % for i=1:M % for j=i+1:M % dist(i,j)=norm(x(i,:)-x(j,:)); % dist(j,i)=dist(i,j); % cosinus=( % dist(i,j)=alpha*dist(i,j)-(1-alpha) % end % end %} busy=c(:,1); % set of numbers for objects already included in some class busy=union(busy,c(:,2)); free=setdiff(1:M,busy); % set of numbers for objects not included in any class yet % main loop of attaching free objects to classes while (length(free)>0) alpha=0.5; % distances between each pair of objects for i=free for j=1:K A=x(c(j,len(j)-1),:); B=x(c(j,len(j)),:); C=x(i,:); cosinus=((B-A)*(C-B)')/(norm(B-A)*norm(C-B)); dist(i,j)=alpha*norm(x(i,:)-x(c(j,len(j)),:))-(1-alpha)*cosinus; end end [mindist1,ind1]=min(dist(free,:),[],1); % ind1 - numbers of nearest busy objects for each free object [mindist2,ind2]=min(mindist1); % ind2 - number of free object with minimum distance to class newclass=ind2; newbusy=free(ind1(ind2)); oldbusy=c(newclass,len(newclass)); % number of busy object with minimum distance to free 'newbusy' object %search class 'oldbusy' object belongs to % for k=1:K % if ismember(oldbusy,c(k,1:len(k))) % newclass=k; % break; % end % end % attaching 'newbusy' object to 'newclass' class c(newclass,len(newclass)+1)=newbusy; len(newclass)=len(newclass)+1; free=setdiff(free,newbusy); busy=union(busy(newclass),newbusy); %plot attachement plot(x([oldbusy newbusy],1),x([oldbusy newbusy],2),'o-','color',color(newclass)) pause end %----- Spiral data generation ---------------------------- function x=spiral(centr,step,dist,ncoin,fi0,dev) i=0; for coin=1:ncoin npoints=ceil(2*pi*dist*(coin+0.5)/step); % number of points in current vitok polar_step=2*pi/npoints; for j=1:npoints [xcur,ycur]=pol2cart(fi0+polar_step*(j-1),dist*(coin+j/npoints)); x(i+1,:)=[xcur,ycur]+dev*(2*rand(1,2)-1)+centr; i=i+1; end end %----- Coincedent spirals data generation ---------------- function x=spiral2(centr,step,dist,ncoin,fi0,dev) x1=spiral(centr,step,dist,ncoin,fi0,dev); x2=spiral(centr,step,dist,ncoin,fi0+pi,dev); x=[x1;x2]; %----- Mixed spirals data generation --------------------- function x=spiralmix(centr1,centr2,step,dist,ncoin,fi0,dev) x1=spiral(centr1,step,dist,ncoin,fi0,dev); x2=spiral(centr2,step,dist,ncoin,fi0+pi,dev); x=[x1;x2];