kmeans matlab算法实现
function kmeans()
clear all;
clc;
k=3;%k为聚类个数
x = 0.8 + sqrt(0.01) * randn(100,2); %随机生成数据集
y = 0.2 + sqrt(0.02) * randn(100,2);
z= 0.5 + sqrt(0.01) * randn(100,2);
% size(x)= 100,2
% plot(x(:,1),x(:,2),'+r',y(:,1),y(:,2),'+b',z(:,1),z(:,2),'+g');
%x1=x(:,1);x2=x(:,2); 从x这个矩阵中取出第一列赋给x1,再从x矩阵中取出第二列赋给x2。执行后x1和x2是两个列向量,分别是x这个矩阵第一列和第二列。
% axis([0,1,0,1]);xlabel('red');ylabel('acc');title('');
D=[x;y;z]; %得到数据集
% size(D)=(300.2)
%plot(D(:,1),D(:,2),'+r'); %可查看初始数据集的分布
u=randperm(size(D,1),k);%随机选k个向量作为初始向量
%p = randperm(n,k) 返回行向量,其中包含在 1 到 n(包括二者)之间随机选择的 k 个唯一整数。
u=D(u,:);
c=zeros(size(D,1),1);%存放聚类标签
distance=zeros(k,1);%存放样本与均值向量的距离。
while 1 %循环开始
mark=0;%标记是否有均值向量更新
for i=1:size(D,1) %size(D,1)=300
for j=1:k
distance(j)=sqrt((D(i,1)-u(j,1))^2+(D(i,2)-u(j,2))^2);%计算样本与均值向量的距离 此时u是确定的
distance(j)%产生三个距离,要取最小
end
% distance %是三元素组,(1,3)
% str = 'Hello World!'
[~,m]=min(distance); %如何因为距离而找到标签123??? 此时m的值也已经确定 m只能等于1 ,2 ,3 ,
%只保留distance 1元数组 的第二个分量的坐标,也就是distance列元素的位置给m,
%因为是按照1 2 3 的顺序求的地址,所以也就是把相应的标签给了m
%min(distance)
% m
% str = 'shange!'
c(i)=m; %把样本的划分到距离最近的簇 此处在分类
%c(i)
% str = 'tx'
% size(distance) =(3,1) 因为k=3
% size(c(i))=(1,1)
%size(c)=(300,1)
%c(i) %永远等于1或者2或者3
end
u1=zeros(k,2); %新的均值向量
for i=1:k %三个均值向量都要更新
u1(i,1)=sum(D(find(c(:)==i),1))/size(find(c(:)==i),1);%计算新的均值向量
% size(find(c(:)==i),1)是每类样本的个数
% sum(D(find(c(:)==i),1))是同一类样本的横坐标的和
u1(i,2)=sum(D(find(c(:)==i),2))/size(find(c(:)==i),1);%计算新的均值向量
size(c)
if u(i,1)~=u1(i,1)||u(i,2)~=u1(i,2)
mark=1;
u(i,1)=u1(i,1);%更新均值向量u 跳到while1
u(i,2)=u1(i,2);
end
end
if mark==0
break;
end
end
a=D(find(c(:)==1),:); %根据簇标签来分类,不同的类别用不同的颜色
b=D(find(c(:)==2),:);
e=D(find(c(:)==3),:);
plot(a(:,1),a(:,2),'+k',b(:,1),b(:,2),'+b',e(:,1),e(:,2),'+g',u(1,1),u(1,2),'*r',u(2,1),u(2,2),'*r',u(3,1),u(3,2),'*r');
axis([0,1,0,1]);xlabel('red');ylabel('acc');title('');
end