接着上篇,继续分析代码。下面就到了MR的循环了,这里MR应该算是比较好理解的,重点是退出循环的条件设置,即如何判断前后两次中心点误差小于给定阈值。

首先,while循环:

 while (iteration <= numIterations) {
conf.set(PRIOR_PATH_KEY, priorPath.toString()); String jobName = "Cluster Iterator running iteration " + iteration + " over priorPath: " + priorPath;
System.out.println(jobName);
Job job = new Job(conf, jobName);
job.setMapOutputKeyClass(IntWritable.class);
job.setMapOutputValueClass(ClusterWritable.class);
job.setOutputKeyClass(IntWritable.class);
job.setOutputValueClass(ClusterWritable.class); job.setInputFormatClass(SequenceFileInputFormat.class);
job.setOutputFormatClass(SequenceFileOutputFormat.class);
job.setMapperClass(CIMapper.class);
job.setReducerClass(CIReducer.class); FileInputFormat.addInputPath(job, inPath);
clustersOut = new Path(outPath, Cluster.CLUSTERS_DIR + iteration);
priorPath = clustersOut;
FileOutputFormat.setOutputPath(job, clustersOut); job.setJarByClass(ClusterIterator.class);
if (!job.waitForCompletion(true)) {
throw new InterruptedException("Cluster Iteration " + iteration + " failed processing " + priorPath);
}
ClusterClassifier.writePolicy(policy, clustersOut);
FileSystem fs = FileSystem.get(outPath.toUri(), conf);
iteration++;
if (isConverged(clustersOut, conf, fs)) {
break;
}
}

这个循环可以看出每个MR的输入都是一样的,输出为outPath+"/clusters-"+iteration ,然后每次MR后就会把同一个policy写入输出里面,循环次数加1,然后判断是否退出循环即isConverged(clustersOut,conf,fs)方法;下面看仿造版的MR。首先看Mapper:

package mahout.fansy.kmeans;

import java.io.IOException;
import java.util.Iterator;
import java.util.List; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.mahout.clustering.Cluster;
import org.apache.mahout.clustering.classify.ClusterClassifier;
import org.apache.mahout.clustering.iterator.ClusterIterator;
import org.apache.mahout.clustering.iterator.ClusterWritable;
import org.apache.mahout.clustering.iterator.ClusteringPolicy;
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.Vector;
import org.apache.mahout.math.VectorWritable;
import org.apache.mahout.math.Vector.Element; import com.google.common.collect.Lists; public class TestCIMapper { /**
* @param args
*/ private static ClusterClassifier classifier; private static ClusteringPolicy policy; public static void main(String[] args) throws IOException {
setup();
map();
cleanup();
} /**
* 仿造setup函数
* @throws IOException
*/
public static void setup() throws IOException{ Configuration conf=new Configuration();
conf.set("mapred.job.tracker", "hadoop:9001"); // 这句是否可以去掉? String priorClustersPath ="hdfs://hadoop:9000/user/hadoop/out/kmeans-output/clusters-0";
classifier = new ClusterClassifier();
classifier.readFromSeqFiles(conf, new Path(priorClustersPath));
policy = classifier.getPolicy();
policy.update(classifier);
}
/**
* 仿造map函数
*/
public static void map(){
List<VectorWritable> vList=getInputData();
for(VectorWritable value: vList){
Vector probabilities = classifier.classify(value.get());
Vector selections = policy.select(probabilities);
for (Iterator<Element> it = selections.iterateNonZero(); it.hasNext();) {
Element el = it.next();
classifier.train(el.index(), value.get(), el.get());
}
}
} /**
* 仿造cleanup函数
*/
public static void cleanup(){
List<Cluster> clusters = classifier.getModels();
ClusterWritable cw = new ClusterWritable();
for (int index = 0; index < clusters.size(); index++) {
cw.setValue(clusters.get(index));
System.out.println("index:"+index+",cw :"+ cw.getValue().getCenter() );
}
} /**
* 获得输入数据
* @return
*/
public static List<VectorWritable> getInputData(){
String input="hdfs://hadoop:9000/user/hadoop/out/kmeans-in-transform/part-r-00000";
Path path=new Path(input);
Configuration conf=new Configuration();
List<VectorWritable> vList=Lists.newArrayList();
for (VectorWritable cw : new SequenceFileDirValueIterable<VectorWritable>(path, PathType.LIST,
PathFilters.logsCRCFilter(), conf)) {
vList.add(cw);
}
return vList;
}
}

上面的代码中的setup函数函数就是把中心点和阈值读入变量而已,比如classifier的变量如下:

其实感觉好像在前面代码的处理中没有必要一个中心点使用一个文件存储吧?这里把这些文件又都读入一个变量了,还要那么多文件干嘛呢?或许这个是某个大神的得意之作,而我还没有发现其精妙之处?还有就是前面的policy变量也应该没有必要存入到文件吧,这里的classifier变量里面都有policy变量了。

下面是map函数,在map函数之前有个getInputData方法用于获得输入数据,把输入数据存入一个变量中。然后在map中foreach读出来。

在map函数中,其实只有这三句有用:

 Vector probabilities = classifier.classify(value.get());
Vector selections = policy.select(probabilities);
classifier.train(el.index(), value.get(), el.get());

第一行,没有设置到关于classifier的代码,第二行也是,第三行虽然设置了classifier中的models属性,但是没有改变其elementData中的center属性,而是改S0,S1之类的,如果这样没有改动的话,那在cleanup里面又是直接输出这个classifier的,那么就等于是没有改到中心点向量,那是怎么更新的呢?额 太困了,下次继续。。。

分享,快乐,成长

转载请注明出处:http://blog.csdn.net/fansy1990

mahout源码KMeansDriver分析之五CIMapper初探的更多相关文章

  1. mahout源码KMeansDriver分析之五CIMapper

    接上文重点分析map操作: Vector probabilities = classifier.classify(value.get());// 第一行 Vector selections = pol ...

  2. mahout源码KMeansDriver分析之四

    昨天说到为什么Configuration没有设置conf.set("mapred.job.tracker","hadoop:9000")仍然可以访问hdfs文件 ...

  3. Mahout源码MeanShiftCanopyDriver分析之二MeanShiftCanopyMapper仿造

    首先更正一点,昨天处理数据的时候是有问题的,直接从网页中拷贝的文件的空格是有问题的,直接拷贝然后新建的文件中的空格可能有一个两个.三个的,所以要把两个或者三个的都换为一个,在InputMapper中下 ...

  4. Mahout源码目录说明&&算法集

    Mahout源码目录说明 mahout项目是由多个子项目组成的,各子项目分别位于源码的不同目录下,下面对mahout的组成进行介绍: 1.mahout-core:核心程序模块,位于/core目录下: ...

  5. mybatis源码配置文件解析之五:解析mappers标签(解析XML映射文件)

    在上篇文章中分析了mybatis解析<mappers>标签,<mybatis源码配置文件解析之五:解析mappers标签>重点分析了如何解析<mappers>标签中 ...

  6. MapReduce的ReduceTask任务的运行源码级分析

    MapReduce的MapTask任务的运行源码级分析 这篇文章好不容易恢复了...谢天谢地...这篇文章讲了MapTask的执行流程.咱们这一节讲解ReduceTask的执行流程.ReduceTas ...

  7. Activity源码简要分析总结

    Activity源码简要分析总结 摘自参考书籍,只列一下结论: 1. Activity的顶层View是DecorView,而我们在onCreate()方法中通过setContentView()设置的V ...

  8. MapReduce的MapTask任务的运行源码级分析

    TaskTracker任务初始化及启动task源码级分析 这篇文章中分析了任务的启动,每个task都会使用一个进程占用一个JVM来执行,org.apache.hadoop.mapred.Child方法 ...

  9. TaskTracker任务初始化及启动task源码级分析

    在监听器初始化Job.JobTracker相应TaskTracker心跳.调度器分配task源码级分析中我们分析的Tasktracker发送心跳的机制,这一节我们分析TaskTracker接受JobT ...

随机推荐

  1. 用python输出汉字字库

    问题1:如果我们知道汉字编码范围是0x4E00到0x9FA5,怎么从十六进制的编码转成人类可读的字呢? 问题2:怎么把unicode编码的字写入文件呢,假设直接用open()的话,会提示Unicode ...

  2. HDU 3177 Crixalis&#39;s Equipment(贪婪)

    主题链接:http://acm.hdu.edu.cn/showproblem.php? pid=3177 Problem Description Crixalis - Sand King used t ...

  3. 使用Visual Studio 2010 创建简单的Silverlight应用程序

    使用Visual Studio 2010 创建简单的Silverlight应用程序 Silverlight是创建动态的引人的RIAs(Rich Internet Application)的新方法.这里 ...

  4. php学习笔记--error

    不同的错误处理方法: 简单的die()语句 自己定义错误函数和错误触发器 错误报告 主要的错误处理:使用die()函数 if(!file_exists("welcome.txt") ...

  5. UVA 1513 - Movie collection(树状数组)

    UVA 1513 - Movie collection option=com_onlinejudge&Itemid=8&page=show_problem&category=5 ...

  6. Gulp实现服务器

    Gulp实现web服务器 Gulp实现web服务器 阅读目录 一:gulp实现web服务器配置: 二:添加实时刷新(livereload)支持 回到顶部 一:gulp实现web服务器配置: 对于前端开 ...

  7. 安装sunvirtualbox

    按照网友提供的方法安装sunvirtualbox,老提示:依赖关系不满足: libpython2.6 (>= 2.6) 后来用终端运行 sudo apt-get install virtualb ...

  8. JDK源码学习系列05----LinkedList

                                             JDK源码学习系列05----LinkedList 1.LinkedList简介 LinkedList是基于双向链表实 ...

  9. java Socket的怪异之处

    怪异之一: connect(SocketAddress endpoint):这个方法,尝试连接server端,如果连接不上,就抛出IOException异常.如果连接成功了,就继续执行下一步的代码. ...

  10. hdu3530Subsequence rmq

    //使用rmq办,ma[i][j],同i作为一个起点2^j阵列的最大长度值 //启动枚举问最长的子列 //枚举的最大长度2^(j-1)和2^(j)z之间 //然后在该范围内找到 #include< ...