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 ...
随机推荐
- C语言 - printf的占位符(%) 异常
printf的占位符(%) 异常 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26719135 C语言中, 使用%代表占位符的意 ...
- Xamarin.Android中使用android:onClick="xxx"属性
原文:Xamarin.Android中使用android:onClick="xxx"属性 在原生Android开发中,为一个View增加点击事件,有三种方式: 1.使用匿名对象 ( ...
- 黄聪:Microsoft Enterprise Library 5.0 系列教程(六) Security Application Block
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(六) Security Application Block 开发人员经常编写需要安全功能的应用程序.这些应用程序 ...
- Android开发之文件下载,状态时显示下载进度,点击自动安装
在进行软件升级时,需要进行文件下载,在这里实现自定义的文件下载,并在状态栏显示下载进度,下载完成后,点击触发安装. 效果如图: 用于下载文件和显示现在进度的线程类如下: [java] view pl ...
- Mybatis数据操作
Maven 工程下 Spring MVC 站点配置 (二) Mybatis数据操作 详细的Spring MVC框架搭配在这个连接中: Maven 工程下 Spring MVC 站点配置 (一) M ...
- SqlServer保留几位小数的两种做法
SqlServer保留几位小数的两种做法 数据库里的 float momey 类型,都会精确到多位小数.但有时候 我们不需要那么精确,例如,只精确到两位有效数字. 解决: 1. 使用 Round( ...
- 802.11(wifi)的MAC层功能
MAC层是802.11的主要功能部分.上层应用通过调用MAC层提供的接口原语调用MAC层的功能. MAC一共向上提供了2大类接口原语,共30种.数据(1)和管理(29).数据部分就是提供普通数据包的收 ...
- 希尔排序java
希尔排序简述 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率.(希尔排序先将部分数据进行排序,相当于已经部分排好序) ...
- Oracle如何插入在特殊字符: & 和 ' (各种解决方案)
分类: Oracle Oracle中怎样插入特殊字符:& 和 ' (多种解决方式) 今天在导入一批数据到Oracle时,碰到了一个问题:Toad提示要给一个自己定义变量AMP赋值,一開始我非常 ...
- 高质量c c++编程
第1章 文件结构 每一个C++/C程序通常分为两个文件.一个文件用于保存程序的声明(declaration),称为头文件.还有一个文件用于保存程序的实现(implementation),称为定义(de ...