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
