文档库 最新最全的文档下载
当前位置:文档库 › matlab实现c均值聚类算法

matlab实现c均值聚类算法

%%%%%%%%%%%%%%%%%%%实现c均值聚类算法(欧式距离)%%%%%%%%%%%%%%%%%%%
%%%%%%%%% 初始中心选择不当可能会导致聚类失败(已改进) %%%%%%%%%%%%%%
%% 1 改进初始聚类中心的选取,先随机选一个然后选与之距离最大的,
%%% 然后选与已有中心加起来聚类最大的
%%% 2 加入类内距离的和J的计算
close all;
clear,clc;
c=4; %聚类数

x=[0,0;4,4;5,0;0,1;1,0;4,5;5,4;5,5;6,0;6,1];


%% 选初始聚类中心
ii_julu=0; %记录距离最大值对应的ii、jj的值
jj_julu=0;

for ll=1:c-1
juli_old=0;
juli=0;
if ll==1
for ii=1:length(x(:,1))
for jj=1:length(x(:,1))
juli=(norm(x(ii,:)-x(jj,:)))^2;
if juli>juli_old
juli_old=juli;
ii_juli=ii;
jj_juli=jj;
end
end
end
chushizhongxin(ll,:)=x(ii_juli,:);
chushizhongxin(ll+1,:)=x(jj_juli,:);
else
for ii=1:length(x(:,1))
cc=1;
for kk=1:ll %排除已经选出的初始中心点
cc=(sum(abs((x(ii,:)-chushizhongxin(kk,:))))&cc);
end
if cc
for kk=1:ll
juli=(norm(x(ii,:)-chushizhongxin(kk,:)))^2+juli;
end
if juli>juli_old
juli_old=juli;
ii_juli=ii;
end
juli=0;
end
end
chushizhongxin(ll+1,:)=x(ii_juli,:);
end
end
% %% 马氏距离的一块内容
% xm=mean(x); %x列向量相加求均值
% v=zeros(length(x(1,:)),length(x(1,:)));
% for l=1:length(x(:,1));
% v=(x(l,:)-xm).'*(x(l,:)-xm)+v;
% end
% v=v./(length(x(:,1))-1);
%%
shuyu=zeros(1,length(x(:,1))); %与样本对应属于哪一类就记为几
% z=zeros(c,length(x(1,:)));
% % for l=1:c; %初始化聚类中心
% % z(l,:)=x(l,:);
% % end
% z(1,:)=x(1,:); %初始的聚类中心可先随机选取第一个
% z(2,:)=x(7,:); %而后选与第一个距离最大的那个
% z(3,:)=x(10,:);
z=chushizhongxin;
yz=z+1; %仅仅是初始化上一次聚类中心

for w=1:10; %迭代次数
if sum(sum(yz~=z)); %矩阵相等的判断后仍是矩阵
yz=z; %进行本次迭代前将记录上次聚类中心

%% 1 聚类 %%%%%%%%%%%%%%%%%%%%%%%%%%
for ll=1:length(x(:,1)); %共有x的列向量个数参加聚类
p=1; %计数值,属于哪一类就记数字几
m=zeros(1,c); %暂存某数与各聚类中心的距离,共c个
for l=1:c;
m(l)=norm(x(ll,:)-z(l,:));%采用欧式距离
%m(l)=(x(ll,:)-z(l,:))*inv(v)*(x(ll,:)-z(l,:)).';%马氏距离
pp=0;
for kk=1:c-1 %排除已经选出

的初始中心点
cc(kk)=(m(l)>m(kk));
end
pp=sum(cc);
if l>1&&~pp
p=l;
end
end
shuyu(ll)=p;
end

%% 2 更改聚类中心 %%%%%%%%%%%%%%%%%%%%%%
xi=zeros(1,c); %记录每一类所含样本数
% for l=1:length(x(:,1));
% for ll=1:c;
% if shuyu(l)==ll;
% xi(ll)=xi(ll)+1; %此处是按123的正序,而实际中不行
% end
% end
% end
psy=zeros(1,c); %记录123出现的次序
pi=1;
for l=1:length(x(:,1));
if ~ismember(shuyu(l),psy); %psy中没有的才记下
psy(pi)=shuyu(l);
pi=pi+1;
end
end

for ll=1:c;
for l=1:length(x(:,1));
if shuyu(l)==psy(ll); %按照psy中123值的顺序记录次数
xi(ll)=xi(ll)+1;
end
end
end

bz=zeros(c,length(x(1,:))); %本次聚类中心
for l=1:c; %shuyu()中有c种类型1到c
for ll=1:length(x(:,1)); %shuyu()有x的列向量个元素
if shuyu(ll)==psy(l);
bz(l,:)=bz(l,:)+x(ll,:); %属于一类的对应位置相加
end
end
end
z=bz;

for l=1:c;
z(l,:)= z(l,:)./xi(l); %除以本类样本个数
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
else
break;
end %15行if的
end %14行for的

% %% 计算类内距离 J
% gg=zeros(1,c);
% jj=1;
% for ii=1:length(x(:,1))
% if ii==1
% gg(jj)=shuyu(ii);
% end
% tt=0;
% hh=jj;
% while hh>0&&ii>1
% tt(hh)=(shuyu(ii)==gg(hh));
% hh=hh-1;
% end
% pp=sum(tt);
% if ii>1&&~pp
% jj=jj+1;
% gg(jj)=shuyu(ii);
% end
% end
%
% J=zeros(1,c);
% leineijuli=0;
% for jj=1:length(x(:,1))
% leineijuli(jj)=norm(x(jj,:)-z(gg(shuyu(jj)),:));
% end
% for ii=1:length(gg)
% for jj=1:length(x(:,1))
% % if ii>1&&shuyu(jj)==gg(ii)
% % J(ii)=J(ii-1)+leineijuli(jj);
% % else
% if shuyu(jj)==gg(ii)
% J(ii)=leineijuli(jj)+J(ii);
% end
% end
% end
%
% sumJ=sum(J);





相关文档
相关文档 最新文档