K-Means(K均值)算法

昨晚在脑内推导了一晚上的概率公式,没推导出来,今早师姐三言两语说用K-Means解决,太桑心了,昨晚一晚上没睡好。

小笨鸟要努力啊,K-Means,最简单的聚类算法,好好实现一下。

思路:

  共有M个样本,设定K值作为样本的聚类个数(K值的设定很讲究,我还没去研究)。

  随机产生K个点作为初始的 类核心。

  do{

    计算M个样本与K个类核心的距离,取距离最小的类核心为该样本的 类别。

    聚一次结束后,根据每个类的样本,计算 聚类的 新 类核心。

  }while(所有的类核心都没有变化,即该系统已经达到稳态,在继续循环下去也是同样的结果);

 

疑问:

  收敛条件,是否能够设定为所有样本距离其类核心的距离和不在变小?

 

实现代码:

 1 #include <stdio.h>
 2 #include <time.h>
 3 #include <stdlib.h>
 4 #include <math.h>
 5 #include <string.h>
 6 #include <limits.h>
 7 
 8 typedef struct Node{
 9     double x;
10     double y;
11     int group;
12 }Node;
13 #define NodeNum 50
14 #define k 10
15 
16 int main(){
17     FILE* f = fopen("in.txt","w+");
18     FILE* f2 = fopen("out.txt","w+");
19     srand((int)time(0));
20     Node node[NodeNum];
21     for(int i = 0 ; i < NodeNum ; i++){
22         node[i].x = 1+(int)(20.0*rand()/(RAND_MAX+1.0)); 
23         node[i].y = 1+(int)(20.0*rand()/(RAND_MAX+1.0));
24     }
25     for(int i = 0 ; i < NodeNum ; i++){
26         printf("x = %.1lf , y = %.1lf\n",node[i].x , node[i].y);
27         fprintf(f,"%.1lf\t%.1lf\n",node[i].x , node[i].y);
28     }
29 
30     Node circle[k];
31     for(int i = 0 ; i < k ; i++){
32         circle[i].x = 1+(int)(20.0*rand()/(RAND_MAX+1.0));
33         circle[i].y = 1+(int)(20.0*rand()/(RAND_MAX+1.0));
34     }
35     for(int i = 0 ; i < k ; i++){
36         printf("circle X= %.1lf , circle Y = %.1lf\n",circle[i].x , circle[i].y);
37         fprintf(f,"%.1lf\t%.1lf\n",circle[i].x , circle[i].y);
38     }
39 
40     int times = 0;
41     bool change = false;
42     do{
43         double sumDis = 0;
44         for(int i = 0 ; i < NodeNum ; i++){
45             double minDis = INT_MAX;    
46             for(int j = 0 ; j < k ; j++){
47                 double curDis = pow((double)abs(node[i].x - circle[j].x),2) + 
48                     pow((double)abs(node[i].y - circle[j].y),2);
49                 if(curDis < minDis){
50                     minDis = curDis;
51                     node[i].group = j;
52                 }
53             }
54             sumDis += minDis;
55         }
56         
57         int newX[k] = {0},newY[k] = {0};
58         for(int j = 0 ; j < k ; j++){
59             int tempX = 0 , tempY = 0 ,count = 0;
60             for(int i = 0 ; i < NodeNum ; i++){
61                 if(node[i].group == j){
62                     count++;
63                     tempX += node[i].x;
64                     tempY += node[i].y;
65                 }
66             }
67             newX[j] = tempX * 1.0 / count;
68             newY[j] = tempY * 1.0 / count;
69         }
70         change = false;
71         for(int i = 0 ; i < k ; i++){
72             if(abs(circle[i].x - newX[i]) > 0.00001 || abs(circle[i].y - newY[i]) > 0.00001 ){
73                 change = true;
74                 break;
75             }
76         }
77         if(change){
78             for(int i = 0 ; i < k ; i++){
79                 circle[i].x = newX[i];
80                 circle[i].y = newY[i];
81             }
82         }
83         printf("times = %d \t ************************* sumDis = %.5lf \n" , times++ , sumDis);
84         /*for(int i = 0 ; i < NodeNum ; i++){
85             printf("x = %.1lf , y = %.1lf , group = %d \n",node[i].x , node[i].y , node[i].group);
86             fprintf(f2,"%.1lf\t%.1lf\t%d\n",node[i].x , node[i].y , node[i].group);
87         }*/
88         for(int m = 0 ; m < k ; m++){
89             printf("circle X = %.1f , circle Y = %.1f\n",circle[m].x , circle[m].y);
90             fprintf(f2,"%.1lf\t%.1lf\n",circle[m].x , circle[m].y);
91         }
92     }while(change);
93 
94     
95     return 0;
96 }

 

 

posted on 2014-03-19 14:29  匡匡锵锵  阅读(312)  评论(0编辑  收藏  举报

导航

AmazingCounters.com