在Spark2.0版本中(不是基于RDD API的MLlib),共有四种聚类方法: 
     (1)K-means 
     (2)Latent Dirichlet allocation (LDA) 
     (3)Bisecting k-means(二分k均值算法) 
     (4)Gaussian Mixture Model (GMM)。 
       基于RDD API的MLLib中,共有六种聚类方法: 
     (1)K-means 
     (2)Gaussian mixture 
     (3)Power iteration clustering (PIC) 
     (4)Latent Dirichlet allocation (LDA)
     (5)Bisecting k-means 
     (6)Streaming k-means 
       多了Power iteration clustering (PIC)和Streaming k-means两种。这些方法后面都会进行介绍。 
本文将介绍三种:K-means、Bisecting k-means与Streaming k-means。其它方法在我Spark机器学习系列里面都有介绍。

k-means

k-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一。K-means算法的基本思想是:以空间中k个点为中心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。 
       假设要把样本集分为c个类别,算法描述如下: 
       (1)适当选择c个类的初始中心; 
       (2)在第k次迭代中,对任意一个样本,求其到c个中心的距离,将该样本归到距离最短的中心所在的类; 
       (3)利用均值等方法更新该类的中心值; 
       (4)对于所有的c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续迭代。 
       该算法的最大优势在于简洁和快速。算法的关键在于初始中心的选择和距离公式。 
       Spark MLlib K-means 算法的实现在初始聚类点的选择上,借鉴了一个叫 K-means || 的类 K-means++ 实现。K-means++ 算法在初始点选择上遵循一个基本原则: 初始聚类中心点相互之间的距离应该尽可能的远。基本步骤如下: 
      第一步,从数据集 X 中随机选择一个点作为第一个初始点。 
      第二步,计算数据集中所有点与最新选择的中心点的距离 D(x)。 
      第三步,选择下一个中心点,使得

最大。

第四部,重复 (二),(三) 步过程,直到 K 个初始点选择完成。

import org.apache.spark.sql.SparkSession
import org.apache.spark.ml.clustering.KMeans
import org.apache.log4j.{Level, Logger} object myClusters {
def main(args:Array[String]){
val spark=SparkSession
.builder()
.appName("myClusters")
.master("local[4]")
.config("spark.sql.warehouse.dir","/home/Spark/spark-warehouse" )
.getOrCreate();
val dataset=spark.read.format("libsvm")
.load("/home/spark-2.0.0-bin-hadoop2.6/data/mllib/sample_kmeans_data.txt") //屏蔽日志
Logger.getLogger("org.apache.spark").setLevel(Level.ERROR)
Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF) //训练kmean模型
val kmeans=new KMeans()
.setK()//表示期望的聚类的个数
.setMaxIter()//表示方法单次运行最大的迭代次数
.setSeed(1L)//集群初始化时的随机种子
val model=kmeans.fit(dataset) // 评估聚类结果误差平方和(Sum of the Squared Error,简称SSE).
val SSE=model.computeCost(dataset)
println(s"within set sum of squared error = $SSE") println("Cluster Centers: ")
model.clusterCenters.foreach(println)
}
}

如何选择K

K 的选择是 K-means 算法的关键,computeCost 方法,该方法通过计算所有数据点到其最近的中心点的平方和来评估聚类的效果。一般来说,同样的迭代次数和算法跑的次数,这个值越小代表聚类的效果越好。但是在实际情况下,我们还要考虑到聚类结果的可解释性,不能一味的选择使 computeCost 结果值最小的那个 K。

KMeans优缺点

优点: 
      原理比较容易理解,容易实现,并且聚类效果良好,有着广泛的使用 
缺点: 
       (1)K-means算法不适用于非球形簇的聚类,而且不同尺寸和密度类型的簇,也不太适合。 
       (2)可能收敛到局部值。

Bisecting k-means(二分K均值算法)

二分k均值(bisecting k-means)是一种层次聚类方法,算法的主要思想是:首先将所有点作为一个簇,然后将该簇一分为二。之后选择能最大程度降低聚类代价函数(也就是误差平方和)的簇划分为两个簇。以此进行下去,直到簇的数目等于用户给定的数目K为止。 
       以上隐含着一个原则是:因为聚类的误差平方和能够衡量聚类性能,该值越小表示数据点月接近于它们的质心,聚类效果就越好。所以我们就需要对误差平方和最大的簇进行再一次的划分,因为误差平方和越大,表示该簇聚类越不好,越有可能是多个簇被当成一个簇了,所以我们首先需要对这个簇进行划分。

bisecting k-means通常比常规K-Means方法运算快一些,也和K-Means聚类方法得到结果有所不同。 
    Bisecting k-means is a kind of hierarchical clustering using a divisive (or “top-down”) approach: all observations start in one cluster, and splits are performed recursively as one moves down the hierarchy. 
    Bisecting K-means can often be much faster than regular K-means, but it will generally produce a different clustering. 
     二分k均值算法的伪代码如下:

将所有的点看成一个簇
当簇数目小于k时
对每一个簇:
计算总误差
在给定的簇上面进行k-均值聚类k=
计算将该簇一分为二后的总误差
选择使得误差最小的那个簇进行划分操作
//BisectingKMeans和K-Means API基本上是一样的,参数也是相同的
//模型训练
val bkmeans=new BisectingKMeans()
.setK()
.setMaxIter()
.setSeed(1L)
val model=bkmeans.fit(dataset) //显示聚类中心
model.clusterCenters.foreach(println) //SSE(sum of squared error)结果评估
val WSSSE=model.computeCost(dataset)
println(s"within set sum of squared error = $WSSSE")

Bisecting k-means优缺点 
       同k-means算法一样,Bisecting k-means算法不适用于非球形簇的聚类,而且不同尺寸和密度的类型的簇,也不太适合。

Streaming k-means 流式k-means

Streaming k-means仍在Mllib RDD-based API中。 
       翻译参考文献(1)和(4)。 
      在streaming环境中,我们的数据是分批到来的,每一批可能包含许多点(样本)的数据。标准k-means算法在streaming环境中最简单的扩展方式是:(a)一开始以随机位置作为聚类的中心,因为这时候我们还没有看到任何的数据。(b)对于新到的每一批数据点,运用前面k-means算法中的(2)、(3)两步骤更新中心点。(c)然后我们就可以用更新后的中心点作为下一批数据更新时的初始中心点,以此反复,随着时间持续运行。 
      In the streaming setting, our data arrive in batches, with potentially many data points per batch. The simplest extension of the standard k-means algorithm would be to begin with cluster centers — usually random locations, because we haven’t yet seen any data — and for each new batch of data points, perform the same two-step operation described above. Then, we use the new centers to repeat the procedure on the next batch. Above is a movie showing the behavior of this algorithm for two-dimensional data streaming from three clusters that are slowly drifting over time. The centers track the true clusters and adapt to the changes over time. 
以一个二维特征的数据流为例,下面的动画展示了这个算法的特点,具有三个中心的数据流在随着时间缓慢漂移,计算出来的三个聚类中心也随之发生改变。 

参考文献: 
(1)Spark document 
http://spark.apache.org/docs/latest/mllib-clustering.html#streaming-k-means 
(2)Spark 实战,第 4 部分: 使用 Spark MLlib 做 K-means 聚类分析 王 龙, 软件开发工程师, IBM,写的非常详细,建议阅读。 
http://www.ibm.com/developerworks/cn/opensource/os-cn-spark-practice4/ 
(3)Bisecting k-means聚类算法实现 http://shiyanjun.cn/archives/1388.html 
(4)Introducing streaming k-means in Apache Spark 1.2 by Jeremy Freemanhttps://databricks.com/blog/2015/01/28/introducing-streaming-k-means-in-spark-1-2.html 
(5)Mahout StreamingKMeans algorithm 
http://mahout.apache.org/users/clustering/streaming-k-means.html

Spark2.0机器学习系列之9: 聚类(k-means,Bisecting k-means,Streaming k-means)的更多相关文章

  1. Spark2.0机器学习系列之11: 聚类(幂迭代聚类, power iteration clustering, PIC)

    在Spark2.0版本中(不是基于RDD API的MLlib),共有四种聚类方法:             (1)K-means             (2)Latent Dirichlet all ...

  2. Spark2.0机器学习系列之10: 聚类(高斯混合模型 GMM)

    在Spark2.0版本中(不是基于RDD API的MLlib),共有四种聚类方法:      (1)K-means      (2)Latent Dirichlet allocation (LDA)  ...

  3. Spark2.0机器学习系列之1: 聚类算法(LDA)

    在Spark2.0版本中(不是基于RDD API的MLlib),共有四种聚类方法:      (1)K-means      (2)Latent Dirichlet allocation (LDA)  ...

  4. Spark2.0机器学习系列之12: 线性回归及L1、L2正则化区别与稀疏解

    概述 线性回归拟合一个因变量与一个自变量之间的线性关系y=f(x).       Spark中实现了:       (1)普通最小二乘法       (2)岭回归(L2正规化)       (3)La ...

  5. Spark2.0机器学习系列之7: MLPC(多层神经网络)

    Spark2.0 MLPC(多层神经网络分类器)算法概述 MultilayerPerceptronClassifier(MLPC)这是一个基于前馈神经网络的分类器,它是一种在输入层与输出层之间含有一层 ...

  6. Spark2.0机器学习系列之5:随机森林

    概述 随机森林是决策树的组合算法,基础是决策树,关于决策树和Spark2.0中的代码设计可以参考本人另外一篇博客: http://www.cnblogs.com/itboys/p/8312894.ht ...

  7. Spark2.0机器学习系列之4:Logistic回归及Binary分类(二分问题)结果评估

    参数设置 α: 梯度上升算法迭代时候权重更新公式中包含 α :  http://blog.csdn.net/lu597203933/article/details/38468303 为了更好理解 α和 ...

  8. Spark2.0机器学习系列之3:决策树

    概述 分类决策树模型是一种描述对实例进行分类的树形结构. 决策树可以看为一个if-then规则集合,具有“互斥完备”性质 .决策树基本上都是 采用的是贪心(即非回溯)的算法,自顶向下递归分治构造. 生 ...

  9. Spark2.0机器学习系列之2:基于Pipeline、交叉验证、ParamMap的模型选择和超参数调优

    Spark中的CrossValidation Spark中采用是k折交叉验证 (k-fold cross validation).举个例子,例如10折交叉验证(10-fold cross valida ...

随机推荐

  1. easyui添加删除tooltip

    /** * 扩展两个方法 */$.extend($.fn.datagrid.methods, { /** * 开打提示功能 * @param {} jq * @param {} params 提示消息 ...

  2. 关于Unity的开发模式

    Unity是组件化的开发模式,总结起来就是节点与组件.节点就像人,组件就像工具,人拿不同的工具,就变成不同的角色,有不同的作用.人+医学常识=医生. 1.每个空节点创建后,刚开始只有一个Transfo ...

  3. 输出JS代码中的变量内容

    一. 输出JS代码中的变量内容 1. 可以直接以提示框的形式输出 alert("输出的内容"); 2. 可以输出到网页的某个位置 a. 在显示输出的位置放一个标签 <a id ...

  4. 【BZOJ】3172: [Tjoi2013]单词(后缀自动机)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3172 随便搞个sam就行了.(其实一开始看到数据n<=200, 单词长度不超过1e6,然后感觉 ...

  5. COCOS2D-X多层单点触摸分发处理方案?

    如今的问题是点击button的时候,会触发底层的触摸事件,怎么不触发底层的触摸事件啊?  

  6. querySelectorAll 和getElementsByClassName的区别

    querySelectorAll 返回的是映射 改变其值不会改变document 而getElementsByClassName 改变它就会改变document 摘自JavaScript权威指南(jQ ...

  7. VC++ LoadLibrary失败,错误127(找不到指定的程序)

    该原因一般是由于DLL或其依赖的DLL使用了高版本的API,而运行时找不到dll中的函数导致的错误. 使用依赖工具查看可能是这样的情况:第一个依赖dll文件小方块中有红色 正常情况下,应该是这样: 解 ...

  8. cocos2dx热更新tmx的一个坑

    游戏项目中使用了tmx地图,当对tmx文件进行热更新时,进入该地图总是宕机,纠结了几小时终于发现,cocos读取tmx文件时,会默认tmx关联的图集文件和tmx在同一目录,然而那个图集文件并没有在热更 ...

  9. ex1. 二维数组中的查找

  10. 通过SSH连接mysql