K-均值算法【有源码】

举报
ShaderJoy 发表于 2021/12/30 00:21:31 2021/12/30
【摘要】 动态聚类方法是模式识别中一种普遍采用的方法,它具有以下3个要点:     1:选定某种距离度量作为样本间的相似性度量     2:确定某个评价聚类结果质量的准则函数     3:给定某个初始分类,然后用迭代算法找出使准则函数取极值的最好的聚类结果...

动态聚类方法是模式识别中一种普遍采用的方法,它具有以下3个要点:
    1:选定某种距离度量作为样本间的相似性度量
    2:确定某个评价聚类结果质量的准则函数
    3:给定某个初始分类,然后用迭代算法找出使准则函数取极值的最好的聚类结果

K-MEANS算法:
输入:聚类个数k,以及包含 n个数据对象的数据库。
输出:满足方差最小标准的k个聚类。

处理流程: 
(1)  从 n个数据对象任意选择 k 个对象作为初始聚类中心;
(2)  循环(3)到(4)直到每个聚类不再发生变化为止;
(3)  根据每个聚类对象的均值(中心对象),计算每个对象与这些中心对象的距离;并根据最小距离重新对相应对象进行划分;
(4)  重新计算每个(有变化)聚类的均值(中心对象)

k-means 算法接受输入量 k ;然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算的。
k-means 算法的工作过程说明如下:首先从n个数据对象任意选择 k 个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。一般都采用均方差作为标准测度函数. k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。


  
  1. /* K-均值算法*/
  2. /*VC++6.0下编译通过*/
  3. #include<stdio.h>
  4. #include<math.h>
  5. void main()
  6. {
  7.  char test='q';
  8.  int i,j,sn1=0,sn2=0,n=0;
  9.  float z1x,z1y,z2x,z2y,z1x_l,z1y_l,z2x_l,z2y_l;
  10.  float X[100][2],S1[100][2],S2[100][2];
  11. /****************************数据输入******************************************/
  12. while(test!=27)
  13. {
  14.  
  15.  printf("Please input the numble of the data:");
  16.  scanf("%d",&n);
  17.  printf("Please input data/n");
  18.  for(i=0;i<n;i++)
  19.  {
  20.   for(j=0;j<2;j++)
  21.   {
  22.    if(j==0)
  23.    {
  24.     printf("X[%d]x=",i+1);
  25.     scanf("%f",&X[i][j]);
  26.    }
  27.    else
  28.    {
  29.     printf("X[%d]y=",i+1);
  30.     scanf("%f",&X[i][j]);
  31.    }
  32.   
  33.   
  34.   }
  35.  }
  36. /*
  37.  printf("Please input K/n");
  38.  scanf("%d",&K);
  39. */
  40. /*******************************算法过程***************************************/
  41.  z1x=z1x_l=X[0][0];//初始化聚类中心
  42.  z1y=z1y_l=X[0][1];
  43.  z2x=z2x_l=X[1][0];
  44.  z2y=z2y_l=X[1][1];
  45. /********************迭代开始*********************/
  46. again:
  47. /*************计算数据点分类**************/
  48.  sn1=0;
  49.  sn2=0;
  50.  for(i=0;i<n;i++)
  51.  {
  52.   if(((X[i][0]-z1x)*(X[i][0]-z1x)+(X[i][1]-z1y)*(X[i][1]-z1y))<((X[i][0]-z2x)*(X[i][0]-z2x)+(X[i][1]-z2y)*(X[i][1]-z2y)))//判断数据所属
  53.   {
  54.    S1[sn1][0]=X[i][0];
  55.    S1[sn1][1]=X[i][1];
  56.    sn1++;
  57.   }
  58.   else
  59.   {
  60.    S2[sn2][0]=X[i][0];
  61.    S2[sn2][1]=X[i][1];
  62.    sn2++;
  63.   }
  64.  }
  65. /*************计算聚类中心**************/
  66.  z1x=0;
  67.  z1y=0;
  68.  for(i=0;i<sn1;i++)
  69.  {
  70.   z1x=(S1[i][0]+z1x);
  71.   z1y=(S1[i][1]+z1y);
  72.  }
  73.  z1x=z1x/(sn1);
  74.  z1y=z1y/(sn1);
  75.  z2x=0;
  76.  z2y=0;
  77.  for(i=0;i<sn2;i++)
  78.  {
  79.   z2x=(S2[i][0]+z2x);
  80.   z2y=(S2[i][1]+z2y);
  81.  }
  82.  z2x=z2x/(sn2);
  83.  z2y=z2y/(sn2);
  84. /*************判断聚类中心**************/
  85.  if((z1x!=z1x_l)||(z1y!=z1y_l)||(z2x!=z2x_l)||(z2y!=z2y_l))
  86.  {
  87.   z1x_l=z1x;
  88.   z1y_l=z1y;
  89.   z2x_l=z2x;
  90.   z2y_l=z2y;
  91.   goto again;//有时候goto还是很好用的,这里判断迭代得出的聚类中心的值是否与上次相同,不同继续迭代
  92.  }
  93.  
  94. /*******************************打印结果***************************************/
  95. printf("%f,%f,%f,%f/nRress Esc to close/nRress any key to continue/n ",z1x,z1y,z2x,z2y);
  96. test=getch(); //按ESC退出
  97. }//回while
  98. }


文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。

原文链接:panda1234lee.blog.csdn.net/article/details/8619269

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。