zoukankan      html  css  js  c++  java
  • 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
    ",node[i].x , node[i].y);
    27         fprintf(f,"%.1lf	%.1lf
    ",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
    ",circle[i].x , circle[i].y);
    37         fprintf(f,"%.1lf	%.1lf
    ",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 	 ************************* sumDis = %.5lf 
    " , times++ , sumDis);
    84         /*for(int i = 0 ; i < NodeNum ; i++){
    85             printf("x = %.1lf , y = %.1lf , group = %d 
    ",node[i].x , node[i].y , node[i].group);
    86             fprintf(f2,"%.1lf	%.1lf	%d
    ",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
    ",circle[m].x , circle[m].y);
    90             fprintf(f2,"%.1lf	%.1lf
    ",circle[m].x , circle[m].y);
    91         }
    92     }while(change);
    93 
    94     
    95     return 0;
    96 }
  • 相关阅读:
    redhat安装opencv
    vsftpd的配置与使用
    Redhat 安装编译 Python-2.7.12
    YUM 安装与配置
    docker安装mysql
    高频问题 java8新特性(转载)
    quartz简单实例实现
    java8线程池
    java8多线程不带返回值
    java8多线程带返回值的
  • 原文地址:https://www.cnblogs.com/glamourousGirl/p/3611339.html
Copyright © 2011-2022 走看看