当前位置:文档之家› matlab实现Kmeans聚类算法

matlab实现Kmeans聚类算法

matlab实现Kmeans聚类算法1.简介:Kmeans和应用于混合高斯模型的受限EM算法是一致的。

高斯混合模型广泛用于数据挖掘、模式识别、机器学习、统计分析。

Kmeans 的迭代步骤可以看成E步和M步,E:固定参数类别中心向量重新标记样本,M:固定均值只考虑(估计)了均值,而没有估计类别的方差,所以聚类的结构比较适合于特征协方差相等的类别。

Kmeans在某种程度也可以看成Meanshitf的特殊版本,Meanshift 是所以Meanshift可以用于寻找数据的多个模态(类别),利用的是梯度上升法。

在06年的一篇CVPR文章上,证明了Meanshift方法是牛顿拉夫逊算法的变种。

Kmeans和EM算法相似是指混合密度的形式已知(参数形式已知)情况下,利用迭代方法,在参数空间中搜索解。

而Kmeans和Meanshift相似是指都是一种概率密度梯度估计的方法,不过是Kmean选用的是特殊的核函数(uniform kernel),而与混合概率密度形式是否已知无关,是一种梯度求解方式。

k-means是一种聚类算法,这种算法是依赖于点的邻域来决定哪些点应该分在点,也可以对高维的空间(3维,4维,等等)的点进行聚类,任意高维的空间都可以。

上图中的彩色部分是一些二维空间点。

上图中已经把这些点分组了,并使用了不同的颜色对各组进行了标记。

这就是聚类算法要做的事情。

这个算法的输入是:1:点的数据(这里并不一定指的是坐标,其实可以说是向量)2:K,聚类中心的个数(即要把这一堆数据分成几组)所以,在处理之前,你先要决定将要把这一堆数据分成几组,即聚成几类。

但并不是在所有情况下,你都事先就能知道需要把数据聚成几类的。

意味着使用k-means就不能处理这种情况,下文中会有讲解。

把相应的输入数据,传入k-means算法后,当k-means算法运行完后,该算法的输出是:1:标签(每一个点都有一个标签,因为最终任何一个点,总会被分到某个类,类的id号就是标签)2:每个类的中心点。

标签,是表示某个点是被分到哪个类了。

例如,在上图中,实际上有4中“标签”,每个“标签”使用不同的颜色来表示。

所有黄色点我们可以用标签以看出,有3个类离的比较远,有两个类离得比较近,几乎要混合在一起了。

当然,数据集不一定是坐标,假如你要对彩色图像进行聚类,那么你的向量就可以是(b,g,r),如果使用的是hsv颜色空间,那还可以使用(h,s,v),当然肯定可以有不同的组合例如(b*b,g*r,r*b) ,(h*b,s*g,v*v)等等。

在本文中,初始的类的中心点是随机产生的。

如上图的红色点所示,是本文随机产生的初始点。

注意观察那两个离得比较近的类,它们几乎要混合在一起,看看算法是如何将它们分开的。

类的初始中心点是随机产生的。

算法会不断迭代来矫正这些中心点,并最终得到比较靠5个中心点的距离,选出一个距离最小的(例如该点与第2个中心点的距离是5个距离中最小的),那么该点就归属于该类.上图是点的归类结果示意图.经过步骤3后,每一个中心center(i)点都有它的”管辖范围”,由于这个中心点不一定是这个管辖范围的真正中心点,所以要重新计算中心点,计算的方法有很多种,最简单的一种是,直接计算该管辖范围内所有点的均值,做为心的中心点new_center(i).如果重新计算的中心点new_center(i)与原来的中心点center(i)的距离大于一定的阈值(该阈值可以设定),那么认为算法尚未收敛,使用new_center(i)代替center(i)(如图,中心点从红色点转移到绿色点),转步骤3;否则,认为算法已经收敛,则new_center(i)就是最终的中心点。

现在,所有的中心都不再移动,即算法已经收敛。

当然,也许这些中心点还没有达。

可以从K=1开始,并且k值不断的增加,通常,随着k的增加,类中的方差会急剧的下降,当k达到一定大的时候,方差的下降会明显减慢(至于慢道何种程度,可以设阈值),此时,就选取到了最佳的k值。

如果初始值没设置好,肯定也不能获得理想的聚类效果。

针对这种情况,这里提供两种方法:随机的选取多组中心点,在每一组中心点上,都把kmeans算法运行一次。

最后,在选取类间方差最小的一组。

通过设定的选初始值方法(这里提供一种,当然自己也可以去构想其他的方法)1.在数据集上随机选择一个点,做为第一个中心点;2:在数据集上,选取离第一个中心点最远的一个点做为第二个中心点。

3:在数据集上,选取离第一个和第二个中心最远的点,做为第三个中心。

4:依此计算后续的中心点2.数据来源描述本次数据挖掘实验的数据源来自加州大学计算机与信息院,是用于合成控制图时间序列聚类分析的一组数据。

数据集中一共包含600组数据,每一组数据都有60个分量,也就是数据是60维的。

数据一共可以分成6个聚类,分别是:3.数据预处理由于本数据集的数据维数较多,所以本实验采用了结构体来存储60维的数据,并使用指针来进行对数据的操作,以提高速度。

在数据预处理过程中,首先将数据从data文件中读出,后依次存入结构体数组dataset[600]中。

4.k-means聚类算法k-means 算法接受参数 k ;然后将事先输入的n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。

聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算的。

K-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一。

K-means算法的基本思想是:以空间中k个点为中心进行聚类,对最靠近他们的对象归类。

通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。

(1)算法思路:首先从n个数据对象任意选择 k 个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。

一般都采用均方差作为标准测度函数. k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。

该算法的最大优势在于简洁和快速。

算法的关键在于初始中心的选择和距离公式。

(2)算法步骤:step.1---初始化距离K个聚类的质心(随机产生)step.2---计算所有数据样本与每个质心的欧氏距离,将数据样本加入与其欧氏距离最短的那个质心的簇中(记录其数据样本的编号)step.3---计算现在每个簇的质心,进行更新,判断新质心是否与原质心相等,若相等,则迭代结束,若不相等,回到step2继续迭代。

Matlab代码:算法流程图三、实验源代码1、主程序clear allclc[FH FW]=textread('C:\Users\lenvo\Desktop\н¨Îļþ¼Ð\FEMALE.txt','%f %f'); [MH MW]=textread('C:\Users\lenvo\Desktop\н¨Îļþ¼Ð\MALE.txt','%f %f'); Data(1:50,1)=FH;Data(51:100,1)=MH;Data(1:50,2)=FW;Data(51:100,2)=MW;C=input('ÊäÈëC£º')[U,P,Dist,Cluster_Res,Obj_Fcn,iter]=fuzzycm(Data,C)plot(Data(:,1), Data(:,2),'o');hold on;maxU = max(U);index1 = find(U(1,:) == maxU);index2 = find(U(2,:) == maxU);line(Data(index1,1),Data(index1,2),'marker','*','color','g');line(Data(index2,1),Data(index2,2),'marker','*','color','r');plot([P([1 2],1)],[P([1 2],2)],'*','color','k')hold off;2、子程序function[U,P,Dist,Cluster_Res,Obj_Fcn,iter]=fuzzycm(Data,C,plotflag,M,epsm)if nargin<5epsm=1.0e-6;endif nargin<4M=2;endif nargin<3plotflag=0;end[N,S]=size(Data);m=2/(M-1);iter=0;Dist(C,N)=0; U(C,N)=0; P(C,S)=0;U0 = rand(C,N);U0=U0./(ones(C,1)*sum(U0));¨while trueiter=iter+1;Um=U0.^M;P=Um*Data./(ones(S,1)*sum(Um'))';for i=1:Cfor j=1:NDist(i,j)=fuzzydist(P(i,:),Data(j,:));endendU=1./(Dist.^m.*(ones(C,1)*sum(Dist.^(-m))));if nargout>4 | plotflagObj_Fcn(iter)=sum(sum(Um.*Dist.^2));endif norm(U-U0,Inf)<epsmbreakendU0=U;endif nargout > 3res = maxrowf(U);for c = 1:Cv = find(res==c);Cluster_Res(c,1:length(v))=v;endendif plotflagfcmplot(Data,U,P,Obj_Fcn);endfunction[U,P,Dist,Cluster_Res,Obj_Fcn,iter]=fuzzycm2(Data,P0,plotflag,M,epsm) if nargin<5epsm=1.0e-6;endif nargin<4M=2;endif nargin<3plotflag=0;end[N,S] = size(Data); m = 2/(M-1); iter = 0;C=size(P0,1);Dist(C,N)=0;U(C,N)=0;P(C,S)=0;while trueiter=iter+1;for i=1:Cfor j=1:NDist(i,j)=fuzzydist(P0(i,:),Data(j,:));endendU=1./(Dist.^m.*(ones(C,1)*sum(Dist.^(-m))));Um=U.^M;P=Um*Data./(ones(S,1)*sum(Um'))';if nargout>4 | plotflagObj_Fcn(iter)=sum(sum(Um.*Dist.^2));endif norm(P-P0,Inf)<epsmbreakendP0=P;endif nargout > 3res = maxrowf(U);for c = 1:Cv = find(res==c);Cluster_Res(c,1:length(v))=v;endendif plotflagfcmplot(Data,U,P,Obj_Fcn);endfunction f = addr(a,strsort)if nargin==1strsort='ascend';endsa=sort(a); ca=a;la=length(a);f(la)=0;for i=1:laf(i)=find(ca==sa(i),1);ca(f(i))=NaN;endif strcmp(strsort,'descend')f=fliplr(f);endfunction ellipse(a,b,center,style,c_3d)if nargin<4style='b';endif nargin<3 | isempty(center)center=[0,0];endt=1:360;x=a/2*cosd(t)+center(1);y=b/2*sind(t)+center(2);if nargin>4plot3(x,y,ones(1,360)*c_3d,style)elseplot(x,y,style)endfunction fcmplot(Data,U,P,Obj_Fcn)[C,S] = size(P); res = maxrowf(U);str = 'po*x+d^v><.h';figure(1),plot(Obj_Fcn)title('Ä¿±êº¯ÊýÖµ±ä»¯ÇúÏß','fontsize',8)if S==2figure(2),plot(P(:,1),P(:,2),'rs'),hold on for i=1:Cv=Data(find(res==i),:);plot(v(:,1),v(:,2),str(rem(i,12)+1))ellipse(max(v(:,1))-min(v(:,1)), ...max(v(:,2))-min(v(:,2)), ...[max(v(:,1))+min(v(:,1)), ...max(v(:,2))+min(v(:,2))]/2,'r:') endgrid on,title('2D ¾ÛÀà½á¹ûͼ','fontsize',8),hold off endif S>2figure(2),plot3(P(:,1),P(:,2),P(:,3),'rs'),hold on for i=1:Cv=Data(find(res==i),:);plot3(v(:,1),v(:,2),v(:,3),str(rem(i,12)+1)) ellipse(max(v(:,1))-min(v(:,1)), ...max(v(:,2))-min(v(:,2)), ...[max(v(:,1))+min(v(:,1)), ...max(v(:,2))+min(v(:,2))]/2, ...'r:',(max(v(:,3))+min(v(:,3)))/2) endgrid on,title('3D ¾ÛÀà½á¹ûͼ','fontsize',8),hold off endfunction D=fuzzydist(A,B)D=norm(A-B);function mr=maxrowf(U,c)if nargin<2c=1;endN=size(U,2);mr(1,N)=0;for j=1:Naj=addr(U(:,j),'descend');mr(j)=aj(c);end四、实验结果1、FEMALE 和 MALE(1)C=2, Z1(1)=(173,53)T, Z2(1)=(168,57)T。

相关主题