mahout算法canopy源码分析之一:获得输入数据
来源:互联网 发布:yum install telnet 编辑:程序博客网 时间:2024/06/05 16:23
对于canopy的输入数据需要的形式为序列文件,同时保证key:Text、value:VectorWritable。昨晚准备打算使用单纯的java程序搞定输入数据的准备,无奈老是会出点问题,昨晚的问题“找不到文件”暂时还没找到原因。
其实如果只是要获得输入数据那么,可以使用mahout官网提供的方法在得到了序列的*.txt文件后直接把mahout-distribution-0.7.zip解压拷贝到虚拟机,(在/etc/profile里面配置下hadoop_home变量)然后找到mahout_home/bin目录,执行 chmod +x mahout ,然后分别执行
./mahout seqdirectory -i <input> -o <output>
./mahout seq2sparse -i <output>/chunk-0 -o <output-in>上面的<input>、<output>对应于自己的输入和输出;我所使用的数据并不是 Reuters dataset的全部数据,而只是前三个:reut2-000.sgm、reut2-001.sgm、reut2-002.sgm,这样的数据在经过ExtractReuters 后生成了3000个文件,然后经过seqdirectory合并成了一个2.41M的数据文件。seq2sparse有7个job,每个job负责自己的内容,这个暂时不加分析;最终的结果在<output-in>/tfidf-vectors里面,即为输入数据;
有了输入数据就可以直接跑程序了,首先不管程序是什么样子的,先跑出结果再说:
package mahout.test.canopy;import java.io.IOException;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.Path;import org.apache.mahout.clustering.canopy.CanopyDriver;import org.apache.mahout.common.distance.DistanceMeasure;import org.apache.mahout.common.distance.EuclideanDistanceMeasure;public class CanopyTest {public static void main(String[] args) throws ClassNotFoundException, IOException, InterruptedException {Configuration conf =new Configuration();conf.set("mapred.job.tracker", "192.168.128.138:9001");Path input=new Path("hdfs://hadoop:9000/user/hadoop/output/canopyvec/tfidf-vectors");Path output=new Path("hdfs://hadoop:9000/user/hadoop/output/canopy-output");DistanceMeasure measure=new EuclideanDistanceMeasure();CanopyDriver.buildClusters(conf, input, output, measure, 33.1, 22.1, 3, false);System.out.println("job is done.");}}最开始的时候我的t1、t2设置为3.1、2.1结果map出来的结果数是为零(这个暂时也不知道是代表什么意思),后来改为上面的结果可以看到map输出了509条记录,reduece输出3条记录(符合参数clusterFileter的设定值:3),最后的输出为:canopy-output/clusters-0-final/part-r-00000。
为了便于后面的观察,所以不使用上面的数据,而使用自己造的数据,造数据之前首先要知道输入数据的格式,那么使用下面的代码看下输入数据是什么:
package mahout.test.utils;import java.io.IOException;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.Path;import org.apache.hadoop.io.Text;import org.apache.hadoop.mapreduce.Job;import org.apache.hadoop.mapreduce.Mapper;import org.apache.hadoop.mapreduce.lib.input.SequenceFileInputFormat;import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import org.apache.hadoop.util.ToolRunner;import org.apache.mahout.common.AbstractJob;import org.apache.mahout.math.Vector;import org.apache.mahout.math.VectorWritable;/** * 读取序列文件,输入Key:Text,Value:VectorWritable * @author fansy * @version 2013/7/21 11:32 * */public class ReadTextVectorWritable extends AbstractJob {@Overridepublic int run(String[] arg0) throws Exception {if(arg0.length!=6||(!"-i".equals(arg0[0])||(!"-o".equals(arg0[2]))||(!"-jt".equals(arg0[4])))){System.err.println("参数不正确!");System.out.println("Usage:");System.out.println("-i <input> -o <output> -jt <jobtracker:port>");System.exit(-1);}Configuration conf=new Configuration();conf.set("mapred.job.tracker", arg0[5]);Job job=new Job(conf);job.setJobName("readTextVector with Input:"+arg0[1]);job.setJarByClass(ReadTextVectorWritable.class);job.setInputFormatClass(SequenceFileInputFormat.class);job.setMapperClass(RM.class);job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(Text.class);job.setNumReduceTasks(0);SequenceFileInputFormat.addInputPath(job, new Path(arg0[1]));FileOutputFormat.setOutputPath(job, new Path(arg0[3]));return job.waitForCompletion(true)? 0:-1;}public static class RM extends Mapper<Text,VectorWritable,Text,Text>{public void map(Text key,VectorWritable value,Context context)throws InterruptedException,IOException{Vector vector=value.get();context.write(key, new Text(vector.asFormatString()));}}public static void main(String[] args) throws Exception{ToolRunner.run(new Configuration(), new ReadTextVectorWritable(), args);}}然后查看hdfs上面的输入数据,如下:
对于上面的数据,其实应该和下面的数据效果是一样的:
1 {1:3.45,2:4.67,3:2.34}2 {1:4.65,3:4.62,3:4.34}3 {1:5.95,5:4.67,3:2.24}第一个代表一个样本号,冒号前面代表维度,冒号后面代表相应维度的大小。猜测:对于reuters数据,应该是把所有的单词全部排序,然后按照一定的规则进行编码(可以是从零到n的编码,所以冒号前面的数字就代表某一个单词),后面的数值应该是该单词在文件中的重要性(?这个应该是有一个pagerank的算法之类的);
有了上面的想法后就可以直接构造一定的输入数据(自己构造少量数据就可以对算法有很清晰的认识),然后把canopy算法的代码改为java代码(不使用hadoop就可以跑的代码),然后就可以进行调试分析其算法逻辑了。
- mahout算法canopy源码分析之一:获得输入数据
- Mahout算法源码(0):搭建环境及Canopy获得输入数据
- Mahout Canopy源码分析
- Mahout聚类算法canopy源码分析(1)
- Mahout源码canopy聚类算法分析(2)
- Mahout源码canopy聚类算法分析(3)
- mahout源码canopy算法分析之三CanopyReducer
- mahout源码canopy算法分析之二CanopyMapper
- Mahout clustering Canopy+K-means 源码分析
- mahout 源码解析之聚类--Canopy算法
- Mahout系列之Canopy聚类算法分析
- mahout之canopy算法简介
- Mahout 系列之--canopy 算法
- mahout源码KMeansDriver分析之一整体分析
- mahout算法数据输入规则
- Mahout关联规则算法源码分析--如何分数据
- Mahout聚类算法学习之Canopy算法的分析与实现
- Mahout-Canopy
- 在Flex库项目中使用defaults.css文件
- Linux ls文件夹颜色(蓝色)的改变方法
- chmod 4755和chmod 755的区别
- POJ 2891 扩展欧几里德
- mahout源码canopy算法分析之二CanopyMapper
- mahout算法canopy源码分析之一:获得输入数据
- ubuntu下 sudo passwd root
- Object-C: 学习实例之继承
- 修改了Ubuntu下的/usr目录权限,导致不能使用sudo命令的修复
- 区间DP——整数划分(使乘积最大)
- 外观模式lua实现
- 逃离北京回家创业--团队组建篇
- 如何调用Android隐藏API
- JAVA系列-设计模式-中介者模式