k-means聚类算法C++实现

原文:http://www.cnblogs.com/luxiaoxun/archive/2013/05/09/3069594.html

Clustering 中文翻译作“聚类”,简单地说就是把相似的东西分到一组,同 Classification (分类)不同,对于一个 classifier ,通常需要你告诉它“这个东西被分为某某类”这样一些例子,理想情况下,一个 classifier 会从它得到的训练集中进行“学习”,从而具备对未知数据进行分类的能力,这种提供训练数据的过程通常叫做 supervised learning (监督学习)。而在聚类的时候,我们并不关心某一类是什么,我们需要实现的目标只是把相似的东西聚到一起,因此,一个聚类算法通常只需要知道如何计算相似 度就可以开始工作了,因此 clustering 通常并不需要使用训练数据进行学习,这在 Machine Learning 中被称作 unsupervised learning (无监督学习)。

在数据挖掘中, k-means聚类算法是一种 cluster analysis (聚类分析)的算法,是一种非常简单地基于距离的聚类算法,认为每个Cluster(类)由相似的点组成而这种相似性由距离来衡量,不同Cluster间的点应该尽量不相似,每个Cluster都会有一个“重心”;另外它也是一种排他的算法,即任意点必然属于某一Cluster且只属于该Cluster。

这个算法实现过程很简单,如下图所示:

上图中,A, B, C, D, E 是五个在图中点。而灰色的点是种子点,也就是用来找Cluster的“重心”。有两个种子点,所以K=2。

k-means算法步骤:

      典型的算法如下,它是一种迭代的算法:

      (1)根据事先给定的k值建立初始划分,得到k个Cluster,比如,可以随机选择k个点作为k个Cluster的重心;

      (2)计算每个点到各个Cluster重心的距离,将它加入到最近的那个Cluster;

      (3)重新计算每个Cluster的重心;

      (4)重复过程2~3,直到各个Cluster重心在某个精度范围内不变化或者达到最大迭代次数。

      别看算法简单,很多复杂算法的实际效果或许都不如它,而且它的局部性较好,容易并行化,对大规模数据集很有意义;算法时间复杂度是:O(nkt),其中:n 是聚类点个数,k 是Cluster个数,t 是迭代次数。

k-means算法主要有两个最重大的缺陷,都和初始值有关:

  • K 是事先给定的,这个 K 值的选定是非常难以估计的。很多时候,事先并不知道给定的数据集应该分成多少个类别才最合适。( ISODATA 算法通过类的自动合并和分裂,得到较为合理的类型数目 K)
  • K-Means算法需要用初始随机种子点来搞,这个随机种子点太重要,不同的随机种子点会有得到完全不同的结果。(K-Means++算法可以用来解决这个问题,其可以有效地选择初始点)

k-means算法C++实现:k-means.rar

GitHub代码:https://github.com/luxiaoxun/k-means

代码来源于网络,稍作修改,并做了简单测试。

posted @ 2015-01-19 18:24  止战  阅读(612)  评论(0编辑  收藏  举报