K均值聚类(K-means)算法及应用(matlab)

来源:互联网 发布:发货单打印软件免费版 编辑:程序博客网 时间:2024/05/22 12:19

一、定义:

       K-means算法是硬聚类算法欧式距离作为相似度测度,它是求对应某一初始聚类中心向量V最优分类,使得评价指标J最小。算法采用误差平方和准则函数作为聚类准则函数。

       k个初始类聚类中心点的选取对聚类结果具有较大的影响,因为在该算法第一步中是随机的选取任意k个对象作为初始聚类的中心,初始地代表一个簇。该算法在每次迭代中对数据集中剩余的每个对象,根据其与各个簇中心的距离将每个对象重新赋给最近的簇。当考察完所有数据对象后,一次迭代运算完成,新的聚类中心被计算出来。如果在一次迭代前后,J的值没有发生变化,说明算法已经收敛。

二、算法过程

1)从N个文档随机选取K个文档作为质心
2)对剩余的每个文档测量其到每个质心的距离,并把它归到最近的质心的类
3)重新计算已经得到的各个类的质心
4)迭代2~3步直至新的质心与原质心相等或小于指定阈值,算法结束
具体如下:
  输入:k, data[n];
(1) 选择k个初始中心点,例如c[0]=data[0],…c[k-1]=data[k-1];
(2) 对于data[0]….data[n],分别与c[0]…c[k-1]比较,假定与c[i]差值最少,就标记为i;
(3) 对于所有标记为i点,重新计算c[i]={ 所有标记为i的data[j]之和}/标记为i的个数;
(4) 重复(2)(3),直到所有c[i]值的变化小于给定阈值。

三、优点

1.算法快速、简单;
2.当聚类是密集的,且类与类之间区别明显时,效果较好。
3.对大数据集有较高的效率并且是可伸缩性的;
4.时间复杂度近于线性,而且适合挖掘大规模数据集。
    K-Means聚类算法的时间复杂度是O(nkt) ,其中n代表数据集中对象的数量,t代表着算法迭代的次数,k代表着簇的数目。

       

四、缺点

1.在 K-means 算法中 K 是事先给定的,这个 K 值的选定是非常难以估计的。有的算法是通过类的自动合并和分裂,得到较为合理的类型数目 K,例如 ISODATA 算法。

 2.在 K-means 算法中,首先需要根据初始聚类中心来确定一个初始划分,然后对初始划分进行优化。这个初始聚类中心的选择对聚类结果有较大的影响,一旦初始值选择的不好,可能无法得到有效的聚类结果,这也成为 K-means算法的一个主要问题。对于该问题的解决,许多算法采用遗传算法(GA),例如文献 中采用遗传算法(GA)进行初始化,以内部聚类准则作为评价指标。

 3.从 K-means 算法框架可以看出,该算法需要不断地进行样本分类调整,不断地计算调整后的新的聚类中心,因此当数据量非常大时,算法的时间开销是非常大的。所以需要对算法的时间复杂度进行分析、改进,提高算法应用范围。


五、我的实际应用简单案例说明

应用场景之一是图像分类:将一幅图像按照某种特征聚类成不同的类别。

例子:以灰度为特征,将一幅图像分成三类。

原灰度图像为:

  

聚类后的结果:(黑色 白色 灰色三类)


matlab代码为:

clcclearclose all%% 对功率灰度图Img进行K-means聚类 分三类Img=imread('C:\Users\xiao\Desktop\邢艳肖的极化分类文件夹\AIRSAR_SanFrancisco11.17开始\图\SPAN_lee5.bmp');Img=Img(1:2:end,1:2:end);imshow(Img);Img=double(Img);%% 各个参数c1=zeros(1,15);c2=zeros(1,15);c3=zeros(1,15); %c存放每次迭代的聚类中心值% 初始聚类中心c1(1)=8;   %海洋c2(1)=20;  %森林c3(1)=80;  %城区%分为三类k=3;   [m,n]=size(Img);%记录迭代次数times=0;%存储分类标识  取值为1 2 3class=zeros(m,n); %存储聚类结果result=zeros(m,n);%存放每类的像素个数和元素总和num1=0;num2=0;num3=0;sum1=0;sum2=0;sum3=0;%先任意给定可以使循环开始的大于1的聚类中心间距值d1=2;d2=2;d3=2;%% 迭代部分ticwhile((d1>0.1||d2>0.1||d3>0.1)&×<15)   %限制迭代次数       times=times+1%%%%%%%%%%%%%%%%%归类%%%%%%%%%%%%%%%%%%%%%%%%%       for i=1:m           for j=1:n               dis1=(Img(i,j)-c1(times))^2;  %欧式距离                dis2=(Img(i,j)-c2(times))^2;               dis3=(Img(i,j)-c3(times))^2;               min_dis=min([dis1,dis2,dis3]);               switch(min_dis)                   case dis1                       class(i,j)=1;                       num1=num1+1;                       sum1=sum1+Img(i,j);                   case dis2                       class(i,j)=2;                        num2=num2+1;                        sum2=sum2+Img(i,j);                   case dis3                       class(i,j)=3;                        num3=num3+1;                        sum3=sum3+Img(i,j);               end              end       end       e_new=sqrt(min_dis);%调整新的聚类中心c1(times+1)=sum1/num1;c2(times+1)=sum2/num2;c3(times+1)=sum3/num3;%两次之间的聚类中心变化大小 以此做为终止迭代的标准d1=abs(c1(times)-c1(times+1));d2=abs(c1(times)-c1(times+1));d3=abs(c1(times)-c1(times+1));%在下一次迭代前将每类的加和置0sum1=0;sum2=0;sum3=0;num1=0;num2=0;num3=0;endtoc%%%%%%%%%%%%将聚类后的功率灰度图赋值%%%%%%%%%%%%%%%%%%%%利用矩阵result(class==1)=0;result(class==2)=130;result(class==3)=255;%显示图像result=uint8(result);  %谨记图像的两种显示格式  uint8和[0,1]imshow(result);title('聚类后的结果');%写入图像imwrite(mat2gray(result),'C:\Users\xiao\Desktop\AIRSAR_SanFrancisco11.17开始\SPAN_cluster.bmp');print('Done');

0 0
原创粉丝点击