Kmeans是最经典的聚类算法之一,它的优美简单、快速高效被广泛使用。

Kmeans算法描述

输入:簇的数目k;包含n个对象的数据集D。

输出:k个簇的集合。

方法:

  1. 从D中任意选择k个对象作为初始簇中心;
  2. repeat;
  3. 根据簇中对象的均值,将每个对象指派到最相似的簇;
  4. 更新簇均值,即计算每个簇中对象的均值;
  5. 计算准则函数;
  6. until准则函数不在发生变化。

Kmeans 算法的优缺点:

1)优点
(1)k-平均算法是解决聚类问题的一种经典算法,算法简单、快速。
(2)对处理大数据集,该算法是相对可伸缩的和高效率的,因为它的复杂度大约是O(nkt),其中n是所有对象的数目,k是簇的数目,t是迭代的次数。通常k<<n。这个算法经常以局部最优结束。
(3)算法尝试找出使平方误差函数值最小的k个划分。当簇是密集的、球状或团状的,而簇与簇之间区别明显时,它的聚类效果很好。
2)缺点
(1)k-平均方法只有在簇的平均值被定义的情况下才能使用,不适用于某些应用,如涉及有分类属性的数据不适用。
(2)要求用户必须事先给出要生成的簇的数目k。
(3)对初值敏感,对于不同的初始值,可能会导致不同的聚类结果。
(4)不适合于发现非凸面形状的簇,或者大小差别很大的簇。
(5)对于"噪声"和孤立点数据敏感,少量的该类数据能够对平均值产生极大影响。

针对算法存在的问题,对K-means算法提出一些改进:一是数据预处理,二是初始聚类中心选择,三是迭代过程中聚类种子的选择。

首先对样本数据进行正规化处理,这样就能防止某些大值属性的数据左右样本间的距离。给定一组含有n个数据的数据集,每个数据含有m个属性,分别计算每一个属性的均值、标准差对每条数据进行标准化。

其次,初始聚类中心的选择对最后的聚类效果有很大的影响,原K-means算法是随机选取k个数据作为聚类中心,而聚类的结果要是同类间尽可能相似,不同类间尽可能相异,所以初始聚类中心的选取要尽可能做到这一点。采用基于距离和的孤立点定义来进行孤立点的预先筛选,并利用两两数据之间的最大距离在剩余数据集合中寻找初始聚类中心。但对于实际数据,孤立点个数往往不可预知。在选择初始聚类中心时,先将孤立点纳入统计范围,在样本中计算对象两两之间的距离,选出距离最大的两个点作为两个不同类的聚类中心,接着从其余的样本对象中找出已经选出来的所有聚类中心的距离和最大的点为另一个聚类中心,直到选出k个聚类中心。这样做就降低了样本输入顺序对初始聚类中心选择的影响。

聚类中心选好以后,就要进行不断的迭代计算,在K-means算法中,是将聚类均值点(类中所有数据的几何中心点)作为新的聚类种子进行新一轮的聚类计算,在这种情况下,新的聚类种子可能偏离真正的数据密集区,从而导致偏差,特别是在有孤立点存在的情况下,有很大的局限性。在选择初始中心点时,由于将孤立点计算在内,所以在迭代过程中要避免孤立点的影响。这里根据聚类种子的计算时,采用簇中那些与第k-1轮聚类种子相似度较大的数据,计算他们的均值点作为第k轮聚类的种子,相当于将孤立点排除在外,孤立点不参与聚类中心的计算,这样聚类中心就不会因为孤立点的原因而明显偏离数据集中的地方。在计算聚类中心的时候,要运用一定的算法将孤立点排除在计算均值点那些数据之外,这里主要采用类中与聚类种子相似度大于某一阈值的数据组成每个类的一个子集,计算子集中的均值点作为下一轮聚类的聚类种子。为了能让更多的数据参与到聚类中心的计算种去,阈值范围要包含大多数的数据。在第k-1轮聚类获得的类,计算该类中所有数据与该类聚类中心的平均距离S,选择类中与聚类种子相似度大于2S的数据组成每个类的一个子集,以此子集的均值点作为第k轮聚类的聚类种子。在数据集中无论是否有明显的孤立点存在,两倍的平均距离都能包含大多数的数据。

对孤立点的改进:

经典k均值算法中没有考虑孤立点。所谓孤立点都是基于距离的, 是数据U集中到U中最近邻居的距离最大的对象, 换言之, 数据集中与其最近邻居的平均距离最大的对象。针对经典k均值算法易受孤立点的影响这一问题, 基于距离法移除孤立点, 具体过程如下:

首先扫描一次数据集, 计算每一个数据对象与其临近对象的距离, 累加求其距离和, 并计算出距离和均值。如果某个数据对象的距离和大于距离和均值, 则视该点为孤立点。把这个对象从数据集中移除到孤立点集合中, 重复直到所有孤立点都找到。最后得到新的数据集就是聚类的初始集合。

对初始点的选择和K值选择的改进:

经典的kmeans 初值选择K值是很难确定的。由于kmeans是局部最优,所以对于初始中心选择很敏感,一方面影响聚类的速度,另一方面影响聚类的质量。一种思路是和其他的聚类算法联合使用,比如Canopy ,谱聚类等。将Canopy和谱聚类执行的结果作为kmeans聚类的输入,这样效果就有了明显的提升。

Mahout Kmeans 聚类:

  1. // 基于内存的 K 均值聚类算法实现
  2. public static void kMeansClusterInMemoryKMeans(){
  3. // 指定需要聚类的个数,这里选择 2 类
  4. int k = 2;
  5. // 指定 K 均值聚类算法的最大迭代次数
  6. int maxIter = 3;
  7. // 指定 K 均值聚类算法的最大距离阈值
  8. double distanceThreshold = 0.01;
  9. // 声明一个计算距离的方法,这里选择了欧几里德距离
  10. DistanceMeasure measure = new EuclideanDistanceMeasure();
  11. // 这里构建向量集,使用的是清单 1 里的二维点集
  12. List<Vector> pointVectors = SimpleDataSet.getPointVectors(SimpleDataSet.points);
  13. // 从点集向量中随机的选择 k 个作为簇的中心
  14. List<Vector> randomPoints = RandomSeedGenerator.chooseRandomPoints(pointVectors, k);
  15. // 基于前面选中的中心构建簇
  16. List<Cluster> clusters = new ArrayList<Cluster>();
  17. int clusterId = 0;
  18. for(Vector v : randomPoints){
  19. clusters.add(new Cluster(v, clusterId ++, measure));
  20. }
  21. // 调用 KMeansClusterer.clusterPoints 方法执行 K 均值聚类
  22. List<List<Cluster>> finalClusters = KMeansClusterer.clusterPoints(pointVectors,
  23. clusters, measure, maxIter, distanceThreshold);
  24.  
  25. // 打印最终的聚类结果
  26. for(Cluster cluster : finalClusters.get(finalClusters.size() -1)){
  27. System.out.println("Cluster id: " + cluster.getId() +
  28. " center: " + cluster.getCenter().asFormatString());
  29. System.out.println(" Points: " + cluster.getNumPoints());
  30. }
  31. }
  32. // 基于 Hadoop 的 K 均值聚类算法实现
  33. public static void kMeansClusterUsingMapReduce () throws Exception{
  34. // 声明一个计算距离的方法,这里选择了欧几里德距离
  35. DistanceMeasure measure = new EuclideanDistanceMeasure();
  36. // 指定输入路径,如前面介绍的一样,基于 Hadoop 的实现就是通过指定输入输出的文件路径来指定数据源的。
  37. Path testpoints = new Path("testpoints");
  38. Path output = new Path("output");
  39. // 清空输入输出路径下的数据
  40. HadoopUtil.overwriteOutput(testpoints);
  41. HadoopUtil.overwriteOutput(output);
  42. RandomUtils.useTestSeed();
  43. // 在输入路径下生成点集,与内存的方法不同,这里需要把所有的向量写进文件,下面给出具体的例子
  44. SimpleDataSet.writePointsToFile(testpoints);
  45. // 指定需要聚类的个数,这里选择 2 类
  46. int k = 2;
  47. // 指定 K 均值聚类算法的最大迭代次数
  48. int maxIter = 3;
  49. // 指定 K 均值聚类算法的最大距离阈值
  50. double distanceThreshold = 0.01;
  51. // 随机的选择 k 个作为簇的中心
  52. Path clusters = RandomSeedGenerator.buildRandom(testpoints,
  53. new Path(output, "clusters-0"), k, measure);
  54. // 调用 KMeansDriver.runJob 方法执行 K 均值聚类算法
  55. KMeansDriver.runJob(testpoints, clusters, output, measure,
  56. distanceThreshold, maxIter, 1, true, true);
  57. // 调用 ClusterDumper 的 printClusters 方法将聚类结果打印出来。
  58. ClusterDumper clusterDumper = new ClusterDumper(new Path(output,
  59. "clusters-" + maxIter -1), new Path(output, "clusteredPoints"));
  60. clusterDumper.printClusters(null);
  61. }
  62. //SimpleDataSet 的 writePointsToFile 方法,将测试点集写入文件里
  63. // 首先我们将测试点集包装成 VectorWritable 形式,从而将它们写入文件
  64. public static List<VectorWritable> getPoints(double[][] raw) {
  65. List<VectorWritable> points = new ArrayList<VectorWritable>();
  66. for (int i = 0; i < raw.length; i++) {
  67. double[] fr = raw[i];
  68. Vector vec = new RandomAccessSparseVector(fr.length);
  69. vec.assign(fr);
  70. // 只是在加入点集前,在 RandomAccessSparseVector 外加了一层 VectorWritable 的包装
  71. points.add(new VectorWritable(vec));
  72. }
  73. return points;
  74. }
  75. // 将 VectorWritable 的点集写入文件,这里涉及一些基本的 Hadoop 编程元素,详细的请参阅参考资源里相关的内容
  76. public static void writePointsToFile(Path output) throws IOException {
  77. // 调用前面的方法生成点集
  78. List<VectorWritable> pointVectors = getPoints(points);
  79. // 设置 Hadoop 的基本配置
  80. Configuration conf = new Configuration();
  81. // 生成 Hadoop 文件系统对象 FileSystem
  82. FileSystem fs = FileSystem.get(output.toUri(), conf);
  83. // 生成一个 SequenceFile.Writer,它负责将 Vector 写入文件中
  84. SequenceFile.Writer writer = new SequenceFile.Writer(fs, conf, output,
  85. Text.class, VectorWritable.class);
  86. // 这里将向量按照文本形式写入文件
  87. try {
  88. for (VectorWritable vw : pointVectors) {
  89. writer.append(new Text(), vw);
  90. }
  91. } finally {
  92. writer.close();
  93. }
  94. }

Mahout系列之----kmeans 聚类的更多相关文章

  1. mahout系列之---谱聚类

    1.构造亲和矩阵W 2.构造度矩阵D 3.拉普拉斯矩阵L 4.计算L矩阵的第二小特征值(谱)对应的特征向量Fiedler 向量 5.以Fiedler向量作为kmean聚类的初始中心,用kmeans聚类 ...

  2. mahout in Action2.2-聚类介绍-K-means聚类算法

    聚类介绍 本章包含 1 实战操作了解聚类 2.了解相似性概念 3 使用mahout执行一个简单的聚类实例 4.用于聚类的各种不同的距离測算方法 作为人类,我们倾向于与志同道合的人合作-"鸟的 ...

  3. Mahout kmeans聚类

    Mahout  K-means聚类 一.Kmeans 聚类原理 K-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一.K-means算法的基本思想是:以空间中k个点为中心进行聚 ...

  4. K-Means 聚类算法

    K-Means 概念定义: K-Means 是一种基于距离的排他的聚类划分方法. 上面的 K-Means 描述中包含了几个概念: 聚类(Clustering):K-Means 是一种聚类分析(Clus ...

  5. 转载: scikit-learn学习之K-means聚类算法与 Mini Batch K-Means算法

    版权声明:<—— 本文为作者呕心沥血打造,若要转载,请注明出处@http://blog.csdn.net/gamer_gyt <—— 目录(?)[+] ================== ...

  6. k-means聚类JAVA实例

    <mahout in action>第六章. datafile/cluster/simple_k-means.txt数据集例如以下: 1 1 2 1 1 2 2 2 3 3 8 8 8 9 ...

  7. Mahout机器学习平台之聚类算法具体剖析(含实例分析)

    第一部分: 学习Mahout必需要知道的资料查找技能: 学会查官方帮助文档: 解压用于安装文件(mahout-distribution-0.6.tar.gz),找到例如以下位置.我将该文件解压到win ...

  8. mahout运行测试与kmeans算法解析

    在使用mahout之前要安装并启动hadoop集群 将mahout的包上传至linux中并解压即可 mahout下载地址: 点击打开链接 mahout中的算法大致可以分为三大类: 聚类,协同过滤和分类 ...

  9. Hadoop平台K-Means聚类算法分布式实现+MapReduce通俗讲解

        Hadoop平台K-Means聚类算法分布式实现+MapReduce通俗讲解 在Hadoop分布式环境下实现K-Means聚类算法的伪代码如下: 输入:参数0--存储样本数据的文本文件inpu ...

随机推荐

  1. Django Views(视图函数)

    http请求中产生两个核心对象: http请求:HttpRequest对象 http响应:HttpResponse对象 所在位置:django.http 之前我们用到的参数request就是HttpR ...

  2. [Gradle系列]Gradle发布module库到jCenter, 并构建自己的企业Maven私服

    Tamic 作者: http://blog.csdn.net/sk719887916/article/details/53224544 前言 andorid开发者经常会看到xx公司发布了xx项目,xx ...

  3. Scikit-learn:模型评估Model evaluation 之绘图

    http://blog.csdn.net/pipisorry/article/details/53001866 绘制ROC曲线 def plotRUC(yt, ys, title=None): ''' ...

  4. Android的Intent机制详解

    Intent 是一个消息传递对象,您可以使用它从其他应用组件请求操作.尽管 Intent 可以通过多种方式促进组件之间的通信,但其 基本用例主要包括以下三个: 启动 Activity: Activit ...

  5. iter 函数另类用法

    它可以很简单地构造一个无限迭代器: ): print(i) #将无限打印出0 原来,如果iter有第二个参数,那么第一个参数必须是一个参数可以省略的可调用对象.int函数符合这种要求. 迭代什么时候停 ...

  6. Dynamics CRM2016 Web API之Expand related entities & $ref & $count

    本篇介绍两个关于1:N关系中通过主实体取关联子实体的api,这两个api会经常被用到而且比原来的odata方式更加方便,之前如果我们要取主实体下所有的关联实体的记录都是通过Retrieve Multi ...

  7. EJB通过ANT提高EJB应用的开发效率、开发具有本地接口的无状态bean、开发有状态bean

    把jboss集成进eclipse 关闭Jboss控制台按Ctrl+c,在MyEclipse→Servers→Jboss里面可以配置JBoss. 通过ANT提高EJB应用的开发效率 在HelloWorl ...

  8. 全文检索概念,Lucene大致结构

    1.1 常见的全文检索 1) 在window系统中,可以指定磁盘中的某一个位置来搜索你想要得到的东西. 2) 在myeclipse中,点击Help->Help Contents,可以利用搜索功能 ...

  9. 内存数据网格IMDG简介

    1 简介 将内存作为首要存储介质不是什么新鲜事儿,我们身边有很多主存数据库(IMDB或MMDB)的例子.在对主存的使用上,内存数据网格(In Memory Data Grid,IMDG)与IMDB类似 ...

  10. Dynamics CRM 将实体从高级查找列表中移除不可见

    有时我们不需要将某个实体显示给一般用户比如配置实体,但是这种类型的实体有时候又需要给一般用户读权限ODATA的时候得能读,站点地图上的隐藏比较容易用工具配置下权限即可.其实做到这步一般就可以了但有的客 ...