ISODATA聚類算法的matlab程序
作者:凱魯嘎吉 - 博客園 http://www.cnblogs.com/kailugaji/
算法簡介:聚類算法:ISODATA算法
數據見:MATLAB實例:PCA降維中的iris數據集,保存為:iris.data,最后一列是類標簽。
demo_isodata.m
clear clc data_load=dlmread('iris.data'); [~,dim]=size(data_load); x=data_load(:,1:dim-1); K=3; theta_N=1; theta_S=1; theta_c=4; L=1; I=5; ISODATA(x,K,theta_N,theta_S,theta_c,L,I)
ISODATA.m
function ISODATA(x,K,theta_N,theta_S,theta_c,L,I) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%input parameters%%%%%% % x : data % K : 預期的聚類中心數 % theta_N : 每一聚類中心中最少的樣本數,少於此數就不作為一個獨立的聚類 % theta_S :一個聚類中樣本距離分布的標准差 % theta_c : 兩聚類中心之間的最小距離,如小於此數,兩個聚類進行合並 % L : 在一次迭代運算中可以和並的聚類中心的最多對數 % I :迭代運算的次數序號 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% step1 n = size(x,1); N_c = K; mean = cell(K,1); for i=1:K mean{i} = x(i,:); end ite = 1; while ite<I flag = 1; while flag %% step2 class = cell(size(mean)); for i=1:n num = Belong2(x(i,:),mean); class{num} = [class{num};x(i,:)]; end %% step3 for i=1:N_c size_i = size(class{i},1); if size_i<theta_N class_i = class{i}; mean = DeleteRow(mean,i); class = DeleteRow(class,i); N_c = N_c-1; for j=1:size_i class_ij = class_i(j,:);%the j'th row of class{i} num = Belong2(class_ij,mean); class{num} = [class{num};class_ij]; end end end %% step4 for i=1:N_c if ~isempty(mean{i}) mean{i} = sum(class{i})./size(class{i},1); end end %% step5 Dis = zeros(N_c,1); for i=1:N_c if ~isempty(class{i}) N_i =size(class{i},1); tmp = bsxfun(@minus,class{i},mean{i}); Dis(i) = sum(arrayfun(@(x)norm(tmp(x,:)),1:N_i))/N_i; end end %% step6 D = 0; for i=1:N_c if ~isempty(class{i}) N_i =size(class{i},1); D = D + N_i*Dis(i); end end D = D/n; %% step7 flag = 0; if ite == I theta_c = 0; flag = 0; elseif ~(N_c > K/2) flag = 1; elseif mod(ite,2)==0 || ~(N_c<2*K) flag = 0; end %% 分裂處理 %% step8 if flag flag = 0; delta = cell(N_c,1); for i=1:N_c if ~isempty(class{i}) N_i =size(class{i},1); tmp = bsxfun(@minus,class{i},mean{i}); delta{i} = arrayfun(@(x)norm(tmp(:,x)),1:size(tmp,2))/N_i; end end %% step9 delta_max = cell(N_c,1); for i=1:N_c if ~isempty(class{i}) max_i = max(delta{i}); sub = find(delta{i}==max_i,1); delta_max{i} = [max_i,sub]; end end %% step10 for i=1:N_c if delta_max{i}(1) > theta_S N_i =size(class{i},1); con1 = (Dis(i)>D && N_i>2*(theta_N + 1)); con2 = ~(N_c>K/2); if con1 || con2 %%%%這里分裂%%%%% flag = 1;%一旦發生分裂,那么分裂一次后就返回第二步;若沒發生分裂,則直接進入合並處理步 lamda = 0.5; max_sub = delta_max{i}(2); mean{i}(max_sub) = mean{i}(max_sub) + lamda * delta_max{i}(1); addOneMean = mean{i}; addOneMean(max_sub) = addOneMean(max_sub) - lamda * delta_max{i}(1); mean = [mean;addOneMean]; N_c = N_c+1; break; end end end end end %% 合並處理 if L %% step11 Distance = zeros(N_c,N_c); for i=1:N_c-1 for j=i:N_c Distance(i,j) = norm(mean{i}-mean{j}); end end %% step12 index = find(-Distance>theta_c); keepIndex = [Distance(index),index]; [~, index] = sort(keepIndex(:,1)); if size(index,1) > L index = index(1:L,:); end %% step13 if size(index,1) ~= 0 for id=1:size(index,1) [m_i m_j]= seq2idx(index(id),N_c); %%%%%這里合並%%%%% N_mi = size(class{m_i},1); N_mj = size(class{m_j},1); mean{m_i} = (N_mi*mean{m_i} + N_mj*mean{m_j})/(N_mi+N_mj); mean = DeleteRow(mean,m_j); class{m_i} = [class{m_i};class{m_j}]; class = DeleteRow(class,m_j); end end end %% step14 ite=ite+1; end for i=1:N_c fprintf('第%d類聚類中心為\n',i); disp(mean{i}); fprintf('第%d類中元素為\n',i); disp(class{i}); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function number = Belong2(x_i,means) INF = 10000; min = INF; kk = size(means,1); number = 1; for i=1:kk if ~isempty(means{i}) if norm(x_i - means{i}) < min min = norm(x_i - means{i}); number = i; end end end end function A_del = DeleteRow(A,r) n = size(A,1); if r == 1 A_del = A(2:n,:); elseif r == n A_del = A(1:n-1,:); else A_del = [A(1:r-1,:);A(r+1:n,:)]; end end function [row col] = seq2idx(id,n) if mod(id,n)==0 row = n; col = id/n; else row = mod(id,n); col = ceil(id/n); end end
結果
>> demo_isodata
第1類聚類中心為 6.6016 2.9857 5.3841 1.9159 第1類中元素為 7.0000 3.2000 4.7000 1.4000 6.4000 3.2000 4.5000 1.5000 6.9000 3.1000 4.9000 1.5000 6.5000 2.8000 4.6000 1.5000 6.3000 3.3000 4.7000 1.6000 6.6000 2.9000 4.6000 1.3000 6.7000 3.1000 4.4000 1.4000 5.9000 3.2000 4.8000 1.8000 6.3000 2.5000 4.9000 1.5000 6.6000 3.0000 4.4000 1.4000 6.8000 2.8000 4.8000 1.4000 6.7000 3.0000 5.0000 1.7000 6.0000 2.7000 5.1000 1.6000 6.7000 3.1000 4.7000 1.5000 6.3000 3.3000 6.0000 2.5000 5.8000 2.7000 5.1000 1.9000 7.1000 3.0000 5.9000 2.1000 6.3000 2.9000 5.6000 1.8000 6.5000 3.0000 5.8000 2.2000 7.6000 3.0000 6.6000 2.1000 7.3000 2.9000 6.3000 1.8000 6.7000 2.5000 5.8000 1.8000 7.2000 3.6000 6.1000 2.5000 6.5000 3.2000 5.1000 2.0000 6.4000 2.7000 5.3000 1.9000 6.8000 3.0000 5.5000 2.1000 5.7000 2.5000 5.0000 2.0000 5.8000 2.8000 5.1000 2.4000 6.4000 3.2000 5.3000 2.3000 6.5000 3.0000 5.5000 1.8000 7.7000 3.8000 6.7000 2.2000 7.7000 2.6000 6.9000 2.3000 6.0000 2.2000 5.0000 1.5000 6.9000 3.2000 5.7000 2.3000 5.6000 2.8000 4.9000 2.0000 7.7000 2.8000 6.7000 2.0000 6.3000 2.7000 4.9000 1.8000 6.7000 3.3000 5.7000 2.1000 7.2000 3.2000 6.0000 1.8000 6.2000 2.8000 4.8000 1.8000 6.1000 3.0000 4.9000 1.8000 6.4000 2.8000 5.6000 2.1000 7.2000 3.0000 5.8000 1.6000 7.4000 2.8000 6.1000 1.9000 7.9000 3.8000 6.4000 2.0000 6.4000 2.8000 5.6000 2.2000 6.3000 2.8000 5.1000 1.5000 6.1000 2.6000 5.6000 1.4000 7.7000 3.0000 6.1000 2.3000 6.3000 3.4000 5.6000 2.4000 6.4000 3.1000 5.5000 1.8000 6.0000 3.0000 4.8000 1.8000 6.9000 3.1000 5.4000 2.1000 6.7000 3.1000 5.6000 2.4000 6.9000 3.1000 5.1000 2.3000 5.8000 2.7000 5.1000 1.9000 6.8000 3.2000 5.9000 2.3000 6.7000 3.3000 5.7000 2.5000 6.7000 3.0000 5.2000 2.3000 6.3000 2.5000 5.0000 1.9000 6.5000 3.0000 5.2000 2.0000 6.2000 3.4000 5.4000 2.3000 5.9000 3.0000 5.1000 1.8000 第2類聚類中心為 5.6838 2.6784 4.0919 1.2676 第2類中元素為 5.5000 2.3000 4.0000 1.3000 5.7000 2.8000 4.5000 1.3000 4.9000 2.4000 3.3000 1.0000 5.2000 2.7000 3.9000 1.4000 5.0000 2.0000 3.5000 1.0000 5.9000 3.0000 4.2000 1.5000 6.0000 2.2000 4.0000 1.0000 6.1000 2.9000 4.7000 1.4000 5.6000 2.9000 3.6000 1.3000 5.6000 3.0000 4.5000 1.5000 5.8000 2.7000 4.1000 1.0000 6.2000 2.2000 4.5000 1.5000 5.6000 2.5000 3.9000 1.1000 6.1000 2.8000 4.0000 1.3000 6.1000 2.8000 4.7000 1.2000 6.4000 2.9000 4.3000 1.3000 6.0000 2.9000 4.5000 1.5000 5.7000 2.6000 3.5000 1.0000 5.5000 2.4000 3.8000 1.1000 5.5000 2.4000 3.7000 1.0000 5.8000 2.7000 3.9000 1.2000 5.4000 3.0000 4.5000 1.5000 6.0000 3.4000 4.5000 1.6000 6.3000 2.3000 4.4000 1.3000 5.6000 3.0000 4.1000 1.3000 5.5000 2.5000 4.0000 1.3000 5.5000 2.6000 4.4000 1.2000 6.1000 3.0000 4.6000 1.4000 5.8000 2.6000 4.0000 1.2000 5.0000 2.3000 3.3000 1.0000 5.6000 2.7000 4.2000 1.3000 5.7000 3.0000 4.2000 1.2000 5.7000 2.9000 4.2000 1.3000 6.2000 2.9000 4.3000 1.3000 5.1000 2.5000 3.0000 1.1000 5.7000 2.8000 4.1000 1.3000 4.9000 2.5000 4.5000 1.7000 第3類聚類中心為 5.0060 3.4180 1.4640 0.2440 第3類中元素為 5.1000 3.5000 1.4000 0.2000 4.9000 3.0000 1.4000 0.2000 4.7000 3.2000 1.3000 0.2000 4.6000 3.1000 1.5000 0.2000 5.0000 3.6000 1.4000 0.2000 5.4000 3.9000 1.7000 0.4000 4.6000 3.4000 1.4000 0.3000 5.0000 3.4000 1.5000 0.2000 4.4000 2.9000 1.4000 0.2000 4.9000 3.1000 1.5000 0.1000 5.4000 3.7000 1.5000 0.2000 4.8000 3.4000 1.6000 0.2000 4.8000 3.0000 1.4000 0.1000 4.3000 3.0000 1.1000 0.1000 5.8000 4.0000 1.2000 0.2000 5.7000 4.4000 1.5000 0.4000 5.4000 3.9000 1.3000 0.4000 5.1000 3.5000 1.4000 0.3000 5.7000 3.8000 1.7000 0.3000 5.1000 3.8000 1.5000 0.3000 5.4000 3.4000 1.7000 0.2000 5.1000 3.7000 1.5000 0.4000 4.6000 3.6000 1.0000 0.2000 5.1000 3.3000 1.7000 0.5000 4.8000 3.4000 1.9000 0.2000 5.0000 3.0000 1.6000 0.2000 5.0000 3.4000 1.6000 0.4000 5.2000 3.5000 1.5000 0.2000 5.2000 3.4000 1.4000 0.2000 4.7000 3.2000 1.6000 0.2000 4.8000 3.1000 1.6000 0.2000 5.4000 3.4000 1.5000 0.4000 5.2000 4.1000 1.5000 0.1000 5.5000 4.2000 1.4000 0.2000 4.9000 3.1000 1.5000 0.1000 5.0000 3.2000 1.2000 0.2000 5.5000 3.5000 1.3000 0.2000 4.9000 3.1000 1.5000 0.1000 4.4000 3.0000 1.3000 0.2000 5.1000 3.4000 1.5000 0.2000 5.0000 3.5000 1.3000 0.3000 4.5000 2.3000 1.3000 0.3000 4.4000 3.2000 1.3000 0.2000 5.0000 3.5000 1.6000 0.6000 5.1000 3.8000 1.9000 0.4000 4.8000 3.0000 1.4000 0.3000 5.1000 3.8000 1.6000 0.2000 4.6000 3.2000 1.4000 0.2000 5.3000 3.7000 1.5000 0.2000 5.0000 3.3000 1.4000 0.2000
2019-10-10 16:10:14