Spark canopy算法
来源:互联网 发布:淘宝刷裁决之镰 编辑:程序博客网 时间:2024/06/05 23:49
canopy算法 概念
与传统的聚类算法(比如K-means)不同,Canopy聚类最大的特点是不需要事先指定k值(即clustering的个数),因此具有很大的实际应用价值。与其他聚类算法相比,Canopy聚类虽然精度较低,但其在速度上有很大优势,因此可以使用Canopy聚类先对数据进行“粗”聚类,得到k值后再使用K-means进行进一步“细”聚类。这种Canopy+K-means的混合聚类方式分为以下两步:
Step1、聚类最耗费计算的地方是计算对象相似性的时候,Canopy聚类在第一阶段选择简单、计算代价较低的方法计算对象相似性,将相似的对象放在一个子集中,这个子集被叫做Canopy ,通过一系列计算得到若干Canopy,Canopy之间可以是重叠的,但不会存在某个对象不属于任何Canopy的情况,可以把这一阶段看做数据预处理;
Step2、在各个Canopy 内使用传统的聚类方法(如K-means),不属于同一Canopy 的对象之间不进行相似性计算。
从这个方法起码可以看出两点好处:首先,Canopy 不要太大且Canopy 之间重叠的不要太多的话会大大减少后续需要计算相似性的对象的个数;其次,类似于K-means这样的聚类方法是需要人为指出K的值的,通过Stage1得到的Canopy 个数完全可以作为这个K值,一定程度上减少了选择K的盲目性。
二、聚类精度
对传统聚类来说,例如K-means、Expectation-Maximization、Greedy Agglomerative Clustering,某个对象与Cluster的相似性是该点到Cluster中心的距离,那么聚类精度能够被很好保证的条件是:
对于每个Cluster都存在一个Canopy,它包含所有属于这个Cluster的元素。 如果这种相似性的度量为当前点与某个Cluster中离的最近的点的距离,那么聚类精度能够被很好保证的条件是: 对于每个Cluster都存在若干个Canopy,这些Canopy之间由Cluster中的元素连接(重叠的部分包含Cluster中的元素)。 数据集的Canopy划分完成后,类似于下图:
三、Canopy算法流程
(1)、将数据集向量化得到一个list后放入内存,选择两个距离阈值:T1和T2,其中T1 > T2,对应上图,实线圈为T1,虚线圈为T2,T1和T2的值可以用交叉校验来确定;
(2)、从list中任取一点P,用低计算成本方法快速计算点P与所有Canopy之间的距离(如果当前不存在Canopy,则把点P作为一个Canopy),如果点P与某个Canopy距离在T1以内,则将点P加入到这个Canopy; (3)、如果点P曾经与某个Canopy的距离在T2以内,则需要把点P从list中删除,这一步是认为点P此时与这个Canopy已经够近了,因此它不可以再做其它Canopy的中心了; (4)、重复步骤2、3,直到list为空结束。
import org.slf4j.Loggerimport org.slf4j.LoggerFactoryimport scala.collection.mutable.HashSetimport spark.SparkContextobject Canopy { def main(args: Array[String]): Unit = { val master = args(0) val input = args(1) val slices = args(2).toInt val output = args(3) val t1 = args(4).toDouble val t2 = args(5).toDouble val lable_separator = "\001" val vector_separator = "," val log = LoggerFactory.getLogger("Canopy") val sc = new SparkContext(master, "Canopy", null, Nil) try { val pairs = sc.textFile(input).map { line => val pair = line.split(lable_separator) (pair(0), pair(1).split(vector_separator).map(_.toDouble)) } val map_centers = new HashSet[(String, Array[Double])] val raw_center_pairs = pairs.map(v => (v._1, canopy_(v, map_centers, t2))).filter(a => a._2 != null).collect().toList val center_pairs = new HashSet[(String, Array[Double])] for (i <- 0 until raw_center_pairs.size) { canopy_(raw_center_pairs(i)._2, center_pairs, t2) } sc.makeRDD(center_pairs.toList, 1).map { pair => pair._1 + pair._2.mkString(",") }.saveAsTextFile(output) } catch { case e: Exception => log.info(e.getStackTrace().mkString("\n")) } sc.stop() } def measure(v1: Array[Double], v2: Array[Double]): Double = { var distance = 0.0 val aa = if (v1.length < v2.length) v1.length else v2.length for (i <- 0 until aa) { distance += scala.Math.pow((v1(i) - v2(i)), 2) } distance } def canopy_(p0: (String, Array[Double]), pair: HashSet[(String, Array[Double])], t2: Double): (String, Array[Double]) = { if (!pair.exists(p => measure(p._2, p0._2) < t2)) { pair += p0 p0 } else { null } }}
参考
程序参考
- Spark canopy算法
- Spark canopy算法
- canopy算法
- Canopy算法
- mapreduce中的canopy算法
- Canopy算法原理
- Canopy算法原理
- Canopy Method算法
- 聚类算法-canopy
- Canopy聚类算法
- Canopy算法原理
- Canopy聚类算法
- Canopy聚类算法
- Canopy聚类算法
- python实现Canopy算法
- Canopy聚类算法说明
- mahout之canopy算法简介
- Canopy聚类算法说明
- 使用openweathermap api 报错401 如何使用openweathermap api 接口
- 一种变进制数及其应用(全排列之Hash实现)
- 使用sqoop将MySQL数据库中的数据导入Hbase
- ES6学习——集合(Collections):Typed Arrays
- JabRef中从当前库中导出选定的参考文献到一个bib文件
- Spark canopy算法
- ELF格式与动态链接库
- win清理垃圾批处理 有源码,比360好多了
- Shellcode的原理及编写
- phoenixframework自动化测试平台1.4.6版本发布
- 【读书笔记】以函数作为算法的实参
- 算法导论第三版 课后习题4.2-7
- 信息模块打线步骤及技巧解读
- 情到深处人孤独,爱至穷时尽沧桑