数据挖掘->Canopy 聚类
来源:互联网 发布:网络兼职宣传语 编辑:程序博客网 时间:2024/06/05 18:34
K-means需要输入聚类个数K以及每个类的聚类中心。K和聚类中心的不同会导致聚类效果的不同,所以取K和聚类中心是个问题。
我们可以先用效率较高的粗聚类,先对数据集进行一个大概的聚类,再将粗聚类得到的聚类个数和聚类中心作为K-means的输入。
Canopy就是一个简单、快速的粗聚类方法(粗:不太准确)
该算法需一种快速的两点之间距离度量方法
可用:
•Jaccardsimilarity coefficient
•Cosinesimilarity
两个距离阈值T1,T2且满足T1>T2。
(本文最后有关于T1\T2取值的一些补充)
上图很好的解释了canopy算法的精髓:(canopy算法中,一个类即为一个canopy)
假设点x与聚类中心的距离为d
d>T1的点,点x不在这个canopy中
d<T1的点,点x在这个canopy中,且在该范围内的点还可以作为其他canopy的聚类中心。
d<T2的点,点x在这个canopy中,但是在该范围内的点不能作为其他canopy的聚类中心了。
单机版算法流程:
输入:点集D,阈值 T1,T2
1.随机取一个点d作为新canopy的聚类中心点,并将d从D中删除
2.计算D中所有点到d的距离
3.距离<T1的点都归到以d为中心的canopy中(注:由于T1>T2 ,则<T1也包括了<T2的点)
4.将所有<T2的点从D中删除(这些点不能再成为新的canopy的中心点了)
5.重复1-4,知道D为空。
这样就能选取Canopy聚类算法得到的canopies的聚类中心作为K-means的输入。
mahout中的Canopy聚类实现:
我没有深入研究源码,把我理解的思路说一下
输入文件为以下形式:每一行代表一个点,每个特征已空格隔开。
1 -0.213 -0.956 -0.003 0.056 0.091 0.017 -0.024 1
1 3.147 2.129 -0.006 -0.056 -0.063 -0.002 0.109 0
1 -2.165 -2.718 -0.008 0.043 -0.103 -0.156 -0.024 1
1 -4.337 -2.686 -0.012 0.122 0.082 -0.021 -0.042 1
...
hadoop将你输入的这个大文件,分割为很多小文件,交给多个mapper并行处理。
CanopyMapper类
1.在其setup阶段,定义一个Canopy集合,设置T1,T2和一个clusterFilter
(canopy中的点需要大于clusterFilter设置的值,该canopy才输出)
2.在map阶段,核心:addPointToCanopies()。
public void addPointToCanopies(Vector point, Collection<Canopy> canopies) {boolean pointStronglyBound = false;for (Canopy canopy : canopies) {// 遍历所有的Canopy,当向量与Canopy的距离小于T1时,将向量加入这个Canopydouble dist = measure.distance(canopy.getCenter().getLengthSquared(), canopy.getCenter(), point);if (dist < t1) {if (log.isDebugEnabled()) {log.debug("Added point: {} to canopy: {}",AbstractCluster.formatVector(point, null),canopy.getIdentifier());}canopy.observe(point);//将point的特征(坐标)来更新canopy的s0 s1 s2,canopy中并没有list等容器来存放属于该canopy中的点。}pointStronglyBound = pointStronglyBound || dist < t2;}// 当canopies为空时将新建canopy,这个用的真奇妙!!if (!pointStronglyBound) {// 当距离大于T2时,新建一个canopyif (log.isDebugEnabled()) {log.debug("Created new Canopy:{} at center:{}", nextCanopyId,AbstractCluster.formatVector(point, null));}canopies.add(new Canopy(point, nextCanopyId++, measure));}}并行会出现一个问题:mapper1中产生的聚类中心C1和mapper2产生的聚类中心C2,他们之间的距离小于T2。如果单机运行的话C2或者C1就不可能两者都作为聚类中心,所以reduce阶段在输出所有mapper的聚类中心前需要解决这一问题。如何解决?那就把所有mapper输出的聚类中心作为输入,再做一次addToCanopies哇。这样距离<T2的就不会再成为聚类中心了。
3.在cleanup阶段,只是简单的将样本向量添加到CanopyClusterer中,在cleanup阶段才更新每个canopy的参数,并将簇样本个数大于阈值的簇输出。
输出 key:"centroid" value:canopy1的聚类中心
key:"centroid" value:canopy2的聚类中心
key:"centroid" value:canopy3的聚类中心……
CanopyReducer类:
1.setup阶段,和map几乎一样,定义一个全新的Canopy集合,只是使用了T3和T4.
2.reduce阶段,因为map阶段输出的key都一样,而且我们在任务设定的时候,指定的reduce个数为1(参见前面Map-Reduce),所以,所有的数据都会传递给唯一的一个reduce。首先addToCanopies(),再来更新每个canopy,再将样本数目大于阈值的簇输出。
输出:canopy的中心点。
canopy中并没有list或其他容器来存放属于该canopy中的点,所以Mahout中通过函数clusterData计算点的归属簇。
map reduce阶段只是得到了各个canopy的聚类中心。
关于T1、T2:
T1决定了每个Cluster包含点的数目,这直接影响了Cluster的“重心”和“半径”,而T2则决定了Cluster的数目,T2太大会导致只有一个Cluster,而太小则会出现过多的Cluster。通过实验,T1和T2取值会严重影响到算法的效果
有人利用AIC、BIC或者交叉验证去做不是很懂,网上也有人给出了这个做法,仅供参考:
- 对数据进行采样。
- 计算所有文档之间的平均距离(使用要在Canopy中用的距离公式)。
- T1 = 平均距离 * 2;T2 = 平均距离。
http://blog.csdn.net/theonlytank2011/article/details/9493115 Mahout 中canopy源码分析,挺详细的
http://www.shahuwang.com/2012/08/14/canopy%E8%81%9A%E7%B1%BB%E7%AE%97%E6%B3%95.html
- 数据挖掘->Canopy 聚类
- 数据挖掘笔记-聚类-Canopy-原理与简单实现
- 数据挖掘笔记-聚类-Canopy-并行处理分析
- 数据挖掘算法之聚类分析(二)canopy算法
- Canopy聚类
- 聚类 - 6 - Canopy聚类
- mahout之canopy聚类
- Mahout Canopy聚类
- Mahout canopy聚类
- Mahout canopy聚类
- 数据挖掘常用技术 聚类
- 数据挖掘(五):聚类
- 数据挖掘(四)聚类
- 数据挖掘(三)聚类
- 数据挖掘--序列挖掘
- 数据挖掘--文本挖掘
- 数据挖掘
- 数据挖掘
- 用Java开发代理服务器
- shell脚本参数
- [Exception记录]elephantbird.class.for.MultiInputFormat
- CoreData debug
- java中String、Long、Double等类型转换问题
- 数据挖掘->Canopy 聚类
- Android开源项目发现---ListView篇
- 欢迎加入91运营网!
- RemoteControlClient的使用
- 捏着鼻子也要吃? 吃蔬菜几大误区盘点
- 摄像头拍照上传
- 测试oracle 11g cluster 中OLR的重要性
- asp.net form认证,在IE10中获取不到cookie?
- 作业2