本篇博客参考:Clustering by fast search and find of density peaks论文以及http://www.cnblogs.com/peghoty/p/3945653.html。
使用版本:
Hadoop版本:2.6.0,Myeclipse:10.0
本地集群情况:
node101 (主节点,namenode,datanode,ResourceManager,NodeManager,SecondaryNamenode,3.7G,2核)
node102 (数据/计算节点,datanode,NodeManager,1G,1核)
上面两个机器是虚拟机,本机是windows7系统4核8G内存;
代码可在https://github.com/fansy1990/fast_cluster下载。
此篇是Hadoop实现Clustering by fast search and find of density peaks的改版,同时此篇只描述了聚类中心点的寻找,代码与Hadoop Web项目--Friend Find系统 里面的聚类实现代码类似,这里使用不同的数据来进行测试而已。
1. 数据格式
本篇测试使用的数据集来自https://www.kaggle.com/c/digit-recognizer/data 中的train.csv ,原始数据是一个数字识别的数据,即把一个数字图片(图片中含有一个手写的数字)转换为784个像素点表示的向量。
测试数据截取了前面的5975条记录,同时针对每条数据,插入了一个id,id从1到5975,数据截图如下:
每行数据的第一列为id,第二列为类别,第3到最后一列为这行记录的所有属性列,一共有784个属性;
2. 本篇用意
2.1. 使用fast cluster(题目的聚类算法),对这份截取后的数据求聚类中心点,然后根据求得的聚类中心点来对原始数据进行分类,在和原始数据做对比,看下正确率,来看下这个聚类算法是否对这个数据有很好的分区性;
2.2. 这样验证之一就是使用fast cluster得到聚类中心后,可以从原始数据中找到该条记录,看到其原始类别,所以这里可以取聚类中心10个点(数字从0~9一共有10组),然后看这10个点是否是“唯一”的(这里的唯一是指原始的类别没有重复);验证之二就是1.里面的争取率了;
2. 3. 此篇在做到求解出聚类中心点后就没有往下继续做了,因为求解出聚类中心点后,发现其不是“唯一”的,里面重复了很多,即聚类中心就是不合理的了,所以就没有往下继续做了。
3. 本篇聚类中心寻找的算法参考:Hadoop Web项目--Friend Find系统 的4.3节1.“执行聚类”一节,具体原理可以参考此篇博客。
4. 运行及实验结果
4.1 原始数据
原始数据截取后的csv文件有10m左右,一共有5975条记录;经过序列化,得到了一个36M的文件(HDFS上)
使用命令:
hadoop jar /opt/fast_cluster.jar fz.fast_cluster.ToSeqJob digit_train.csv seq_out ,
其中,fast_cluster.jar是源码打包得到的文件;
4.2 计算距离
这一步计算距离是比较耗时的,距离计算即计算原始数据中两两之间的距离,原始数据一共有5975条记录,那么这里的输出即是5975*(5975-1)/2条记录,运行命令如下:
hadoop jar /opt/fast_cluster.jar fz.fast_cluster.CalDistanceJob seq_out cal_distance_out
得到的距离文件为400多M,此MR耗时24分钟(可以想象如果使用70M的数据,那么其耗时和输出是多大!)如下:
4.3 根据距离数据求解每个向量的最小距离和局部密度,并画决策图
命令为:
hadoop jar /opt/fast_cluster.jar fz.fast_cluster.CalDiffDCFindVec cal_distance_out/part-r-00000 17847325 0.02 0.02 1 2 2 /opt/picandlog 500
参数对应的变量为<path> <numRecords> <from> <to> <howMany> <localDensityNumReducer> <deltaDistanceNumReducer> <localSavePath> <numPoints> ,每个参数的意思为:
<path> 距离的文件所在路径;
<numRecords> 输出的距离数据的记录数;
<from> 阈值开始的百分比;
<to>阈值结束的百分比;
<howMany> 阈值的个数; 因为在求解局部密度的时候需要输入一个距离阈值,根据论文说可以选择全部距离的前面1~2%的记录的距离作为此参数值,所以这里的意思是可以使用不同的阈值来画出最后的决策图,看哪个决策图表现最好,就选择那个阈值;但是lz使用虚拟机资源有限,所以这里就没有循环,即开始从2%,结束也是2%,阈值的个数为1个,来完成;
<localDensityNumReducer> 局部密度的MR的reducer个数;(我有两个节点,所以这里设置为2)
<deltaDistanceNumReducer> 最小距离MR的reducer个数;
<localSavePath> 这里会把生成的决策图以及按照局部密度和最小距离乘积的值从大到小排序取<numPoints>个值的<向量id,局部密度,最小距离>数据写入本地的路径;
<numPoints> 上面使用的numPoints即是;
这里得到的决策图为:
这里黑色框里面的数据及可以作为聚类中心向量(这里的阈值为局部密度>500,最小距离>1000),因为局部密度最大以及最小距离最大的点没有画出来,所以这里取9个点(一共要取10个点);
4.4 根据距离和密度阈值求得聚类中心并写入本地
运行的命令为:
hadoop jar /opt/fast_cluster.jar fz.fast_cluster.FindWriteCenter /opt/picandlog/log_center_0.dat 500 1000 digit_train.csv center_out /opt/picandlog/center.dat
查看/opt/picandlog/center.dat文件,可以得到下面的数据:
这里可以看到的确是有10个聚类中心向量,但是可以看到参考原始数据的类型值,发现其中9、1、3是重复的,即聚类中心本身就存在问题。得到这样的结果可以推测原因如下:
1). 原始数据的聚类特征不明显,从而得到的结果效果不好;
2.) 聚类的阈值选择,在计算局部密度时,阈值选择的不同,其结果可能也是大相径庭的;
5. 总结
1)该算法首先要计算距离,但是距离的计算所需的资源很大;
2)聚类时阈值的选择,没有定量的分析,需要在一定经验上选择;
3)从聚类决策图 中选择聚类中心点也是人工的经验,很多不确定性;
由于使用该数据在得到聚类中心后和原始数据对比没有得到比较理想的结果,所以这里就不往下做了!
分享,成长,快乐
脚踏实地,专注
转载请注明blog地址:http://blog.csdn.net/fansy1990
版权声明:本文为博主原创文章,未经博主允许不得转载。