K-Means算法的输入N,K和一个size为N的向量组vector.输出K个两两互不相交的向量组.其本质是将给定的向量组划分成K个类别,使得同类别的向量相似度比较大,而不同类别的向量之间的相似度较小.
    比如以下这个图,人肉眼能看出有四个点团,但计算机不知道,为了让计算机明白这一点,可以将点的坐标提取到向量组中,而向量之间的相似度定义为点之间的距离的相反数或者倒数.从而将这些点分开.
    实现过程:
    (1)从n个数据对象任意选择k个对象作为初始聚类中心;
    (2)根据每个聚类对象的均值(中心对象),计算每个对象与这些中心对象的距离,并根据最小距离重新对相应对象进行划分;
    (3)重新计算每个(有变化)聚类的均值(中心对象);
    (4)计算标准测度函数,当满足一定条件,如函数收敛时,则算法终止,如果条件不满足则回到步骤(2).
    实际应用中的问题:
    事实上,我是一个做ACM的选手,所以我比较感兴趣的是K-Means能否求得一个最优解.对于这样一个问题:从N个点取出K个作为核心,定义两个向量之间的相似度函数f(vector1,vector2),使得所有点与其所对应的核心的相似度之和最大.然而事实让我大失所望,K-Means算法对种子点的选取十分敏感,不同的种子会导致不同的解.

#include<math.h>
#include<stdio.h>
#include<string.h>
#define Convergence (fabs(last-cur)<1e-8)
#define dist(a,b) (sqrt((x[a]-px[b])*(x[a]-px[b])+(y[a]-py[b])*(y[a]-py[b])))
int x[],y[],qx[],qy[],px[],py[],assign[];
int main()
{
freopen("data.txt","r",stdin);
FILE *fp=fopen("output.txt","w");
int N,K,i,j,k;
double ave=,MIN=1e15;
scanf("%d%d",&N,&K);
for (i=;i<=N;i++) scanf("%d%d",&x[i],&y[i]);
for (int asd=;asd<N;asd++)
{
printf("Executing case #%d\n",asd);
if (asd) printf("Current Average:%.6lf\n",ave/asd);
printf("Current Minimize:%.6lf\n",MIN);
printf("----------------------------------------\n");
fprintf(fp,"Executing case #%d\n",asd);
if (asd) fprintf(fp,"Current Average:%.6lf\n",ave/asd);
fprintf(fp,"Current Minimize:%.6lf\n",MIN);
fprintf(fp,"----------------------------------------\n");
for (i=;i<=K;i++)
{
px[i]=x[(i+asd)%N+];
py[i]=y[(i+asd)%N+];
}
double last=1e15,cur=;
while (!Convergence)
{
printf("%.6lf\n",last);
last=cur;
for (i=;i<=N;i++)
{
double Min=1e15;
int v;
for (j=;j<=K;j++)
{
double d=dist(i,j);
if (d<Min)
{
Min=d;
v=j;
}
}
assign[i]=v;
}
for (i=;i<=K;i++)
{
int cnt=;
for (j=;j<=N;j++)
if (assign[j]==i)
{
qx[++cnt]=x[j];
qy[ cnt ]=y[j];
}
double Min=1e15;
int v;
for (j=;j<=cnt;j++)
{
double tmp=;
for (k=;k<=cnt;k++)
tmp+=(sqrt((qx[j]-qx[k])*(qx[j]-qx[k])+(qy[j]-qy[k])*(qy[j]-qy[k])));
if (tmp<Min)
{
Min=tmp;
v=j;
}
}
px[i]=qx[v];
py[i]=qy[v];
}
cur=;
for (i=;i<=N;i++) cur+=dist(i,assign[i]);
}
ave+=cur;
MIN=MIN<cur ? MIN:cur;
}
printf("Total average:%.6lf\n",ave/N);
printf("Total MIN:%.6lf\n",MIN);
fprintf(fp,"Total average:%.6lf\n",ave/N);
fprintf(fp,"Total MIN:%.6lf\n",MIN);
return ;
}

运行结果如图所示:


    另一个问题是算法的收敛速度,重新算了一下,结果如下图所示:


    这个结果让我大吃一惊啊,每次迭代之后更新量都很小,而且最终的值(9259914.963696)跟第一个有意义的值(10352922.175732)相差并不是很多.后来我仔细想了一下,应该是跟输入数据有关,我的数据完全是在一定范围内随机生成的,分布比较均匀,所以即使随便选也可以得到相当不错的效果,这是我生成数据的程序:

program makedata;
var i,N,K:longint;
begin
assign(output,'data.txt');
rewrite(output);
randomize;
N:=random();
K:=random();
writeln(N,' ',K);
for i:= to N do
writeln(random(),' ',random());
close(output);
end.

于是我重新写了makedada程序,想法是先随机生成K个核心,再在其周围生成其他的点:

#include<stdio.h>
#include<time.h>
#include<math.h>
#include<stdlib.h>
int main()
{
srand(unsigned(time()));
freopen("data.txt","w",stdout);
printf("15000 15\n");
for (int i=;i<=;i++)
{
int X=rand()%,Y=rand()%;
for (int j=;j<=;j++)
{
int dx=rand()%,dy=rand()%;
if (rand()&) dx*=-;
if (rand()&) dy*=-;
printf("%d %d\n",X+dx,Y+dy);
}
}
return ;
}

再重新运行一下,得到如下结果:


    可以看出,收敛的速度还是可以的,而且最终结果几乎只有最初解得一半.
    初除此之外,还有一个重要问题,核心数K是作为输入给定的,而在实际应用中是无法预知的.对此可以用ISODATA算法作为补充.

数据挖掘十大经典算法[0]-K-Means算法的更多相关文章

  1. 数据挖掘十大经典算法(5) 最大期望(EM)算法

    在统计计算中,最大期望(EM,Expectation–Maximization)算法是在概率(probabilistic)模型中寻找参数最大似然估计的算法,其中概率模型依赖于无法观测的隐藏变量(Lat ...

  2. ICDM评选:数据挖掘十大经典算法

    原文地址:http://blog.csdn.net/aladdina/article/details/4141177 国际权威的学术组织the IEEE International Conferenc ...

  3. 数据挖掘十大经典算法--CART: 分类与回归树

    一.决策树的类型  在数据挖掘中,决策树主要有两种类型: 分类树 的输出是样本的类标. 回归树 的输出是一个实数 (比如房子的价格,病人呆在医院的时间等). 术语分类和回归树 (CART) 包括了上述 ...

  4. 数据挖掘十大经典算法(9) 朴素贝叶斯分类器 Naive Bayes

    贝叶斯分类器 贝叶斯分类器的分类原理是通过某对象的先验概率,利用贝叶斯公式计算出其后验概率,即该对象属于某一类的概率,选择具有最大后验概率的类作为该对象所属的类.眼下研究较多的贝叶斯分类器主要有四种, ...

  5. 数据挖掘领域十大经典算法之—C4.5算法(超详细附代码)

    https://blog.csdn.net/fuqiuai/article/details/79456971 相关文章: 数据挖掘领域十大经典算法之—K-Means算法(超详细附代码)        ...

  6. 数据挖掘十大算法--K-均值聚类算法

    一.相异度计算  在正式讨论聚类前,我们要先弄清楚一个问题:怎样定量计算两个可比較元素间的相异度.用通俗的话说.相异度就是两个东西区别有多大.比如人类与章鱼的相异度明显大于人类与黑猩猩的相异度,这是能 ...

  7. 【十大经典数据挖掘算法】k

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 1. 引言 k-means与kNN虽 ...

  8. 【十大经典数据挖掘算法】PageRank

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 我特地把PageRank作为[十大经 ...

  9. 【十大经典数据挖掘算法】SVM

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART SVM(Support Vector ...

随机推荐

  1. mongo链接报错:couldn't connect to server 127.0.0.1:27017 (127.0.0.1)

    angela@angeladeMacBook-Air:/data/db$mongo MongoDB shell version: 2.6.1 connecting to: test 2014-06-0 ...

  2. HDU2546(01背包饭卡)

    电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够).所以大家 ...

  3. TexBox的属性

    允许多行输入

  4. jstl数字转日期

    <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <jsp: ...

  5. 玩转ubuntu FAQ

    一.用wubi安装ubuntu的时候自动重新下载 1.双击ubuntu.ios让windows加载这个镜像 2.断开网络 二.安装其他程序时提示Error: Dependency is not sat ...

  6. web开发中目录路径问题的解决

    web开发当中,目录路径的书写是再常用不过了,一般情况下不会出什么问题,但是有些时候出现了问题却一直感到奇怪,所以这里记录一下,彻底解决web开发中路径的问题,开发分为前端和服务端,那么就从这两个方面 ...

  7. 使用JS构建简单Map(转)

    转载自:http://freejvm.iteye.com/blog/768025 最近使用源生的js处理页面数据,所谓源生的就是指没有经过包装的.最基本的JavaScript代码: 像使用ext,jQ ...

  8. 安装绿色版mysql

    #修改my.ini basedir = "D:\tools\mysql-5.7.13-winx64" datadir = "D:\tools\mysql-5.7.13-w ...

  9. sublime 实用 快捷键

    alt+- 向后导航 alt+shift+- 向前导航 ctrl+shift+↑↓ 上下移动一行 ctrl+k,ctrl+u 转换所选为大写 ctrl+k,ctrl+l(字母L) 转换所选为小写 ct ...

  10. primace 5.0软件的Debug ware 功能的使用方法简介

    用primace 软件已经一年多了,一直不知道Debug ware 软件怎么使用,上周终于逮住FAE请教了下这个功能的使用方法.发现这个功能和signalTap ii 原理不一样,这个是非时事的波形, ...