首先说下,为什么题目后面会有个“无语篇”,因为我觉得今晚这几个钟头太坑爹了。为什么,且听我慢慢道来:

按照昨天的计划,我应该把代码仿造成单机可运行的代码。但是首先我要有输入数据不是?所以我最开始做的就是仿造clusterIn的数据,即中心向量的文件。昨天也说过中心向量文件应该就是把一组(key,value)对(要求value的格式为ClusterWritable,key格式任意)写入一个序列文件即可,然后使用

KMeansUtil.configureWithClusterInfo(conf, clustersIn, clusters);

这个就可以玩儿了,所以我编写了下面的代码:

package mahout.fansy.test.kmeans;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.apache.mahout.clustering.Cluster;
import org.apache.mahout.clustering.canopy.Canopy;
import org.apache.mahout.clustering.iterator.ClusterWritable;
import org.apache.mahout.clustering.kmeans.Kluster;
import org.apache.mahout.common.distance.ManhattanDistanceMeasure;
import org.apache.mahout.common.iterator.sequencefile.PathFilters;
import org.apache.mahout.common.iterator.sequencefile.PathType;
import org.apache.mahout.common.iterator.sequencefile.SequenceFileDirValueIterable;
import org.apache.mahout.math.RandomAccessSparseVector;
import org.apache.mahout.math.Vector;
public class TestConfigureWithClusterInfo {public static void main(String[] args) throws IOException {//    testWrClWr(); // 测试函数testConfig();System.out.println("done...");} /*** 把一个double数组写入sequence file,格式为 ClusterWritable* @param center double数组* @param output 输出路径* @throws IOException */public static void writeClusterWritable(String output,double[][] center) throws IOException{Configuration conf =new Configuration();conf.set("mapred.job.tracker", "hadoop:9001");FileSystem fs=FileSystem.get(URI.create(output),conf);Path path=new Path(output);Text key =new Text();ClusterWritable value=new ClusterWritable();SequenceFile.Writer writer = null;  try {  writer = SequenceFile.createWriter(fs, conf, path,  key.getClass(), value.getClass(),SequenceFile.CompressionType.NONE);  // here changefor (int i = 0; i < center.length; i++) {  key.set("C-"+String.valueOf(i));  Vector v=new RandomAccessSparseVector(center[0].length);for(int j=0;j<center[0].length;j++){v.set(j, i*4+Math.random());}Canopy canopy=new Canopy(v,i,new ManhattanDistanceMeasure());value.setValue(canopy);  //      System.out.printf("[%s]\t%s\t%s\n", writer.getLength(), key, value);  writer.append(key, value);  }  } finally {  IOUtils.closeStream(writer);  }  }/*** 测试writeClusterWritable() 是否ok* @throws IOException */public static void testWrClWr() throws IOException{double[][] center=new double[][]{{0.1,0.2,0.3},{10,12,13}};// String path="hdfs://hadoop:9000/user/hadoop/output/test-configureCluster";//     String path="hdfs://hadoop:9000/user/hadoop/output/test-configureCluster1";String path="hdfs://hadoop:9000/user/hadoop/output/test-configureCluster2";writeClusterWritable(path,center);}/*** 把序列文件读入到一个变量中;* @param clusterPath 序列文件* @param conf  Configuration* @return  序列文件读取的变量*/public static List<Cluster> testConfigureWith(Path clusterPath,Configuration conf){List<Cluster> clusters = new ArrayList<Cluster>();for (Writable value : new SequenceFileDirValueIterable<Writable>(clusterPath, PathType.LIST,PathFilters.partFilter(), conf)) {Class<? extends Writable> valueClass = value.getClass();if (valueClass.equals(ClusterWritable.class)) {ClusterWritable clusterWritable = (ClusterWritable) value;value = clusterWritable.getValue();valueClass = value.getClass();}//   log.debug("Read 1 Cluster from {}", clusterPath);if (valueClass.equals(Kluster.class)) {// get the cluster infoclusters.add((Kluster) value);} else if (valueClass.equals(Canopy.class)) {// get the cluster infoCanopy canopy = (Canopy) value;clusters.add(new Kluster(canopy.getCenter(), canopy.getId(), canopy.getMeasure()));} else {throw new IllegalStateException("Bad value class: " + valueClass);}}return clusters;}/*** testConfigureWith() 的测试程序*/public static void testConfig(){//   Path clusterPath=new Path("hdfs://hadoop:9000/user/hadoop/test-conf");//     Path clusterPath=new Path("hdfs://hadoop:9000/user/hadoop/output/test-configureCluster");//  Path clusterPath=new Path("hdfs://hadoop:9000/user/hadoop/output/test-configureCluster1");Path clusterPath=new Path("hdfs://hadoop:9000/user/hadoop/output/part-test-configureCluster1");//   Path clusterPath=new Path("hdfs://hadoop:9000/user/hadoop/output/test-configureCluster2");//     Path clusterPath=new Path("hdfs://hadoop:9000/user/hadoop/output/part-test-configureCluster2");//    Path clusterPath=new Path("hdfs://hadoop:9000/user/hadoop/output/test_canopy1/clusters-0-final/part-r-00000");// test ok//   Path clusterPath=new Path("hdfs://hadoop:9000/user/hadoop/output/test_canopy1/clusters-0-final");  // test ok;Configuration conf=new Configuration();conf.set("mapred.job.tracker", "hadoop:9001");testConfigureWith(clusterPath, conf);}}

首先 看writeClusterWritable()函数,这个函数就是把一个double[][]数组的数据放入到一个序列文件中,且保证按着key是Text,value是ClusterWritable的格式写入的。testWrClWr()是这个函数的测试函数,来验证这个是否ok。所以我运行了,然后在hdfs上查看这个文件:

一看,感觉ok哦应该可以的吧,所以我就又写了上面的testConfigureWith()方法,即把含有中心点的向量文件按照mahout里面的方法读入一个变量中,然后使用testConfig()方法进行测试,直接在testConfigureWith()的return一行设置断点,直接运行,我X,clusters居然是空的?神马情况?然后我就感觉不会是我猜错了吧,这么命苦?

然后怎么办,继续想办法呗,我们对待bug就要有越战越勇的精神,不然我这么晚了还在这里写blog?好吧,我有点无聊了。

对了,那么直接使用canopy最后产生的文件是否可以读的出来呢?我就又改了之前分析canopy的代码了,之前是把txt直接读入,然后生成的中心点文件也是txt类型的,如下所示:

然后这次只是把CanopyDriver的输出类型改为sequence的了,直接加上一句:

job.setOutputFormatClass(SequenceFileOutputFormat.class);

就可以了。

然后可以查看新的文件是:


感觉这个和刚才的差别多嘛,不管了,试试吧。直接改路径为这个,然后跑testConfig()方法,嗨呀,居然clusters有值了。oh,my god。我说原来确实这个文件可以作为中心点文件呀,和我猜的差不多嘛。哎,不过怎么我自己写的不行呢?对照两个文件的显示,我看到了一点,好像我写入的有压缩?

是哦,会不会是压缩的问题?恩 ,有可能。怎么去掉压缩呢?网上找方法呗(总之找了有15分钟吧)可以进行设置的,在上面代码中的这里:

 writer = SequenceFile.createWriter(fs, conf, path,  key.getClass(), value.getClass(),SequenceFile.CompressionType.NONE);  // here change

之前是没有SequenceFile.CompressionType.NONE这个参数的,然后我就加入了,继续运行 testWrClWr()进行写文件,得到下面的文件:


哈哈,这次没有了吧,我再运行testConfig()方法,断点调试,我艹,我都不想说粗口了,还不行,现在时间已经去到了1点了亲,还不行?我还睡不睡啦。为什么clusters还是空?没理由吧,都是一样的啦。怎么会这样?这个时候我就会想,原来奋斗是这么苦逼的一件事。。。

对了,调试。既然两个文件都是一样的,那我一步步调试不就可以发现他们的不同了么?好吧,开始调试

。。。

居然是.class文件?好吧,我把hadoop的源码也拷贝过来吧。继续调试。。。

然后发现在类SequenceFileDirValueIterator的70行两个文件得到的status是不一样的,我产生的是空,而canopy的是有值的。所以进一步,然后我就发现了惊人的一幕,在FileSystem中的一个方法:

private void listStatus(ArrayList<FileStatus> results, Path f,PathFilter filter) throws IOException {FileStatus listing[] = listStatus(f);if (listing != null) {for (int i = 0; i < listing.length; i++) {if (filter.accept(listing[i].getPath())) {results.add(listing[i]);}}}}

对于中心点文件的验证,accept()方法(好吧,这个不是吃惊的地方,在下面),进入accept,然后(要进入的是PathFilter的方法):

private static final PathFilter PART_FILE_INSTANCE = new PathFilter() {@Overridepublic boolean accept(Path path) {String name = path.getName();return name.startsWith("part-") && !name.endsWith(".crc");}};

好吧,你看到了,程序居然要求我们的中心点文件以“part-”开头,且不能以“.crc”结尾,好吧,我彻底无语了。为啥我的中心点文件一定要以“part-”开头,我自己新建一个不行嘛?不行嘛?好吧,我不粗口了,我准备睡觉了。

然后我把我的文件改名为part-开头,然后可以读取我产生的文件了。还有一点,这个和是否压缩没有关系,不压缩,只要你的文件是以part-开头也是可以读取的。好吧,睡了,明天还要上班。。。

Mahout源码K均值聚类算分析(2)相关推荐

  1. 基于K均值聚类的葡萄酒品种判别

    特别注意:主要思路.程序和分析过程来源于:https://www.kaggle.com/xvivancos/tutorial-clustering-wines-with-k-means.本文在此基础上 ...

  2. K均值聚类算法(Kmeans)讲解及源码实现

    K均值聚类算法(Kmeans)讲解及源码实现 算法核心 K均值聚类的核心目标是将给定的数据集划分成K个簇,并给出每个数据对应的簇中心点.算法的具体步骤描述如下. 数据预处理,如归一化.离群点处理等. ...

  3. 聚类分析 | MATLAB实现k-Means(k均值聚类)分析

    目录 聚类分析 | MATLAB实现k-Means(k均值聚类)分析 k-均值聚类简介 相关描述 程序设计 学习小结 参考资料 致谢 聚类分析 | MATLAB实现k-Means(k均值聚类)分析 k ...

  4. K均值聚类(KMeans)、可视化选取最佳K值、通过TSNE进行结果可视化分析、抽取核心特征因子

    K-means算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大.该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标. k ...

  5. 模糊C均值聚类算法的实现

     模糊C均值聚类算法的实现 研究背景 聚类分析是多元统计分析的一种,也是无监督模式识别的一个重要分支,在模式分类 图像处理和模糊规则处理等众多领域中获得最广泛的应用.它把一个没有类别标记的样本按照 ...

  6. 机器学习作业9 - 自动确定k值的k均值聚类

    自动确定k值的k均值聚类 说实话刚刚看到这个作业我是懵逼的.k均值本身不难,可是要自动确定k值,我就不知所措了.于是脑补了无数种方法,最后决定求助度娘.研究了几个小时以后,渐渐有了思路,于是一步步展开 ...

  7. Python,OpenCV中的K均值聚类——K-Means Cluster

    Python,OpenCV中的K均值聚类 1. 效果图 2. 原理 2.1 什么是K均值聚类? 2.2 K均值聚类过程 2.3 cv2.kmeans(z, 2, None, criteria, 10, ...

  8. Python OpenCV应用K均值聚类进行颜色量化

    Python OpenCV应用K均值聚类进行颜色量化 1. 效果图 2. 颜色量化是什么? 3. MiniBatchKMeans & KMeans 4. 源码 参考 在这篇博客文章中,我将向您 ...

  9. 机器学习工程师 — Udacity 电影评分的 k 均值聚类

    电影评分的 k 均值聚类 假设你是 Netflix 的一名数据分析师,你想要根据用户对不同电影的评分研究用户在电影品位上的相似和不同之处.了解这些评分对用户电影推荐系统有帮助吗?我们来研究下这方面的数 ...

最新文章

  1. To connect to files.phpmyadmin.net insecurely, use `--no-check-certificate‘
  2. 脑植入芯片实现脑机交互,脑神经链会如星链般放大马斯克的光环吗
  3. [react] props.children.map和js的map有什么区别?为什么优先选择react的?
  4. Matlab——对比度拉伸
  5. react antd confirm content list_react简单的项目架构搭建过程
  6. Web App:赌的就是互联网未来并 非无可挑剔
  7. esp8266 米家_【保姆级教程】米家全屋智能家居避坑指南+新手必购单品推荐(2020版)_智能家居...
  8. 宋宝华:谈一谈Linux写时拷贝(COW)的安全漏洞(1)
  9. 西门子触摸屏HTML控件,西门子HMI触摸屏操作手册.pdf
  10. Exadata通过ILOM远程MOUNT ISO实现刷机Reimage
  11. 高斯消去法(Gauss)的python实现
  12. 《战神》全剧情对话超详尽攻略
  13. 村田 - ESD 保护装置的基础知识
  14. 国产AT2401c完全替代RFX2401C直接兼容软件硬件
  15. 营造平安 信息化使公交事业更加人性化
  16. CentOS7 下安装 MySQL5.7 (包含mysql安装报错处理)
  17. rjs 中的一些记下 免的忘 了
  18. 一起装逼!开平方的七种算法
  19. Ipopt with Metis编译指南
  20. 最新手机号验证正则表达式(电信、移动、广电号段)

热门文章

  1. 冲压过程中,冲裁力的变化过程
  2. GL error Invalid operation:Optix7官方Demo奇怪问题解决方案
  3. 如何制作视频黑白效果
  4. c语言和线性代数哪个难,学编程数学到底有多重要?线性代数能否视为一门程序语言呢?...
  5. ros 接入Livox Mid-70
  6. Git - Your branch and 'origin/xxx' have diverged
  7. HTML5学习之header、footer、address等标签作用。
  8. FireEye 666漏洞
  9. 鸿蒙分布式跨屏,华为推出智慧屏 SE 系列新品,搭载鸿蒙分布式跨屏技术
  10. 递归算法——八皇后问题 python