要求:
(1)迭代过程中,每一轮迭代、每一类样本的总数、错分的个数、相应的错误率;
(2)画图展示每一轮迭代中,这几个类别的类中心与上一次类中心的总误差变化趋势。(一般来说,是随着迭代次数增加而快速减小的),或者称为纵坐标为在其上进行聚类的准确率。
(3)在图中做出每一轮迭代中,类中心点和不同类别归属。可以用不同颜色、不同标记。
图中可看出,误差平方和与分类数的拐点为k=2;可确定分类个数k=2为最佳分类个数;一般来说我们不考虑分类个数为1的情况,剔除掉分类个数为1的情况后,发现图中没有明显拐点且呈类线性关系,因此可认为最佳分类个数即为k=2。
% 已知20个样本,每个样本有两个特征
% K-means方法的MATLAB实现
% 数据的准备和初始化
clc
clear
x=[0 0;1 0;0 1;1 1;2 1;1 2;2 2;3 2;6 6;7 6;8 6;
6 7;7 7;8 7;9 7;7 8;8 8;9 8;8 9;9 9];
%设置类标签
for i=1 : 20
if(i<=8)
x(i,3)=1;
else
x(i,3)=2;
end
end
z=zeros(2,2);
z1=zeros(2,2);
%z=x(:,1);
test=x(1:2,2);
%z=x(1:2,1:2);%初始聚类中心为第一第二个样本
%z=[6 6;7 6];%初始聚类中心为随机样本
z=rand([2,2])*10; %生成一个2行2列的随机数矩阵
j=1;
ErrNum=0;
times=0;
%初始样本分布图与聚类中心
figure(1);
gscatter(x(:,1),x(:,2),x(:,3));
hold on
plot(z(:,1),z(:,2),'k*',...
'LineWidth',1,...
'MarkerSize',5,...
'MarkerFaceColor',[0.5,0.5,0.5])
set(gca,'Linewidth',1);
title('初始样本分布图与聚类中心');
temp1Sum=0;
temp2Sum=0;
%%寻找聚类中心
while 1
count=zeros(2,1);
allsum=zeros(2,2);
ErrNum=0;
times=times+1;
fprintf('第%d轮计算\n',times);
for i=1:20 %对每一个样本i,计算到两个聚类中心的距离
temp1=sqrt((z(1,1)-x(i,1)).^2+(z(1,2)-x(i,2)).^2);
temp2=sqrt((z(2,1)-x(i,1)).^2+(z(2,2)-x(i,2)).^2);
%fprintf('第%d个样本temp1=%f,temp2=%f\n',i,temp1,temp2);
if(temp1<temp2)
temp1Sum=temp1Sum+temp1;
label(i,1)=1;
if(x(i,3)==2)
ErrNum=ErrNum+1;
fprintf('第%d个样本分类错误!\n',i);
end
count(1)=count(1)+1;%第一类个数
allsum(1,1)=allsum(1,1)+x(i,1);%所有第一类的坐标累加
allsum(1,2)=allsum(1,2)+x(i,2);
else
label(i,1)=2;
temp2Sum=temp2Sum+temp2;
if(x(i,3)==1)
ErrNum=ErrNum+1;
fprintf('第%d个样本分类错误!\n',i);
end
count(2)=count(2)+1;%第二类个数
allsum(2,1)=allsum(2,1)+x(i,1);%所有第二类的坐标累加
allsum(2,2)=allsum(2,2)+x(i,2);
end
end
fprintf('第%d轮错误个数为:%d错误率为%f\n',times,ErrNum,ErrNum/20);
%取均值,迭代新的聚类中心
z1(1,1)=allsum(1,1)/count(1);
z1(1,2)=allsum(1,2)/count(1);
z1(2,1)=allsum(2,1)/count(2);
z1(2,2)=allsum(2,2)/count(2);
figure(j+1)
gscatter(x(:,1),x(:,2),label(:,1));
% plot( x(:,1),x(:,2),'k*',...
% 'LineWidth',2,...
% 'MarkerSize',10,...
% 'MarkerEdgeColor','k',...
% 'MarkerFaceColor',[0.5,0.5,0.5])
hold on
plot(z1(:,1),z1(:,2),'k*',...
'LineWidth',1,...
'MarkerSize',5,...
'MarkerFaceColor',[0.5,0.5,0.5])
set(gca,'Linewidth',1);
title(sprintf('第%d次迭代图', j))
% title('K-means分类图','fontsize',12);
if(z==z1)
break;
else
fprintf('第%d轮后聚类中心为:\n',j);
disp(z1);
fprintf('\n');
z=z1;
j=j+1;
end
end
%%结果显示
fprintf('最终聚类中心:\n');
disp(z1); %输出聚类中心
gscatter(x(:,1),x(:,2),label(:,1));
% plot( x(:,1),x(:,2),'k*',...
% 'LineWidth',2,...
% 'MarkerSize',10,...
% 'MarkerEdgeColor','k',...
% 'MarkerFaceColor',[0.5,0.5,0.5])
hold on
plot(z1(:,1),z1(:,2),'k*',...
'LineWidth',1,...
'MarkerSize',5,...
'MarkerFaceColor',[0.5,0.5,0.5])
set(gca,'Linewidth',1);
title('K-means分类图','fontsize',12);