mahout源码KMeansDriver分析之五CIMapper初探
接着上篇,继续分析代码。下面就到了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初探的更多相关文章
- mahout源码KMeansDriver分析之五CIMapper
接上文重点分析map操作: Vector probabilities = classifier.classify(value.get());// 第一行 Vector selections = pol ...
- mahout源码KMeansDriver分析之四
昨天说到为什么Configuration没有设置conf.set("mapred.job.tracker","hadoop:9000")仍然可以访问hdfs文件 ...
- Mahout源码MeanShiftCanopyDriver分析之二MeanShiftCanopyMapper仿造
首先更正一点,昨天处理数据的时候是有问题的,直接从网页中拷贝的文件的空格是有问题的,直接拷贝然后新建的文件中的空格可能有一个两个.三个的,所以要把两个或者三个的都换为一个,在InputMapper中下 ...
- Mahout源码目录说明&&算法集
Mahout源码目录说明 mahout项目是由多个子项目组成的,各子项目分别位于源码的不同目录下,下面对mahout的组成进行介绍: 1.mahout-core:核心程序模块,位于/core目录下: ...
- mybatis源码配置文件解析之五:解析mappers标签(解析XML映射文件)
在上篇文章中分析了mybatis解析<mappers>标签,<mybatis源码配置文件解析之五:解析mappers标签>重点分析了如何解析<mappers>标签中 ...
- MapReduce的ReduceTask任务的运行源码级分析
MapReduce的MapTask任务的运行源码级分析 这篇文章好不容易恢复了...谢天谢地...这篇文章讲了MapTask的执行流程.咱们这一节讲解ReduceTask的执行流程.ReduceTas ...
- Activity源码简要分析总结
Activity源码简要分析总结 摘自参考书籍,只列一下结论: 1. Activity的顶层View是DecorView,而我们在onCreate()方法中通过setContentView()设置的V ...
- MapReduce的MapTask任务的运行源码级分析
TaskTracker任务初始化及启动task源码级分析 这篇文章中分析了任务的启动,每个task都会使用一个进程占用一个JVM来执行,org.apache.hadoop.mapred.Child方法 ...
- TaskTracker任务初始化及启动task源码级分析
在监听器初始化Job.JobTracker相应TaskTracker心跳.调度器分配task源码级分析中我们分析的Tasktracker发送心跳的机制,这一节我们分析TaskTracker接受JobT ...
随机推荐
- spring4.1+springmvc4.1+mybatis3.2.8+spring-security3.2.5集成环境建设
在最近使用的项目ssi+spring-security 结构体.建立你自己的家,这是什么环境. 只有记录的目的. 项目结构: 类文件: ...
- Java&Android反编工具打包
Java&Android反编工具: 1.Eclipse反编插件:安装到Eclipse后,可以简要的查看jar包中的*.class; 2.DoAPK:反编*.apk为smali和一些资源文件,可 ...
- Uva11464 开关问题
给一个n×n的01矩阵,你的任务是将尽量少的0变成1,是的每个元素的上下左右的位置(如果存在的话)的之和均为偶数.1<=n<=15. 如果暴力整个矩阵,那么时间复杂度是O(2^(n*n)) ...
- windows phone 页面传值(7)
原文:windows phone 页面传值(7) 在windows phone 中微软为我们提供了页面间传递参数的解决方案,下面就为大家介绍使用方法,页面传值的案例中我们建立两个页面,一个是MainP ...
- 飘逸的python - 发送带各种类型附件的邮件
上一篇博文演示了如何发送简单的邮件,这一篇将演示如何发送各种类型的附件. 基本思路就是,使用MIMEMultipart来标示这个邮件是多个部分组成的,然后attach各个部分.如果是附件,则add_h ...
- 原创教程“ActionScript3.0游戏中的图像编程”開始连载啦!
经过近两年的不懈努力,笔者的原创教程"ActionScript3游戏中的图像编程"最终在今日划上了完美的句号!这其中记录着笔者多年来在游戏制作,尤其是其中图像处理方 ...
- java 线程 新类库中的构件 countDownLatch 使用
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlhbmdydWkxOTg4/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- 尺取法 poj3061 poj3320
尺取法就是反复推进区间的开头和结尾,来求满足条件的最下区间. poj3061 http://poj.org/problem?id=3061 给定一个都是正整数的序列,要我们求总和不小于S的连续子序列的 ...
- activity点击时各种方法的区别
用到不同方法时候某些系统有不太一样的情况: public class MainActivity extends Activity { private static String TAG = " ...
- TCP/IP详细说明--滑模、拥塞窗口、慢启动、Negle算法
TCP的数据流大致能够分为两类,交互数据流与成块的数据流. 交互数据流就是发送控制命令的数据流.比方relogin,telnet.ftp命令等等.成块数据流是用来发送数据的包,网络上大部分的TCP包都 ...