mahout贝叶斯算法开发思路(拓展篇)1

首先说明一点,此篇blog解决的问题是就下面的数据如何应用mahout中的贝叶斯算法?(这个问题是在上篇(。。。完结篇)blog最后留的问题,如果想直接使用该工具,可以在mahout贝叶斯算法拓展下载):

 

0.2	0.3	0.4:1
0.32	0.43	0.45:1
0.23	0.33	0.54:1
2.4	2.5	2.6:2
2.3	2.2	2.1:2
5.4	7.2	7.2:3
5.6	7	6:3
5.8	7.1	6.3:3
6	6	5.4:3
11	12	13:4


前篇blog上面的数据在最后的空格使用冒号代替(因为样本向量和标识的解析需要不同的解析符号,同一个的话解析就会出问题)。关于上面的数据其实就是说样本[0.2,0.3,0.4]被贴上了标签1,其他依次类推,然后这个作为训练数据训练贝叶斯模型,最后通过上面的数据进行分类建议模型的准确度。

 

处理的过程大概可以分为7个步骤:1.转换原始数据到贝叶斯算法可以使用的数据格式;2. 把所有的标识转换为数值型格式;3.对原始数据进行处理获得贝叶斯模型的属性参数值1;4.对原始数据进行处理获得贝叶斯模型的属性参数值2;5.根据3、4的结果把贝叶斯模型写入文件;6.对原始数据进行自分类;7.根据6的结果对贝叶斯模型进行评价。

下面分别介绍:

1. 数据格式转换:

代码如下:

 

package mahout.fansy.bayes.transform;import java.io.IOException;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
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.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;
import org.apache.hadoop.util.ToolRunner;
import org.apache.mahout.common.AbstractJob;
import org.apache.mahout.common.HadoopUtil;
import org.apache.mahout.math.NamedVector;
import org.apache.mahout.math.RandomAccessSparseVector;
import org.apache.mahout.math.Vector;
import org.apache.mahout.math.VectorWritable;public class TFText2VectorWritable extends AbstractJob {/*** 处理把* [2.1,3.2,1.2:a* 2.1,3.2,1.3:b]* 这样的数据转换为 key:new Text(a),value:new VectorWritable(2.1,3.2,1.2:a) 的序列数据* @param args* @throws Exception */public static void main(String[] args) throws Exception {ToolRunner.run(new Configuration(), new TFText2VectorWritable(),args);}@Overridepublic int run(String[] args) throws Exception {addInputOption();addOutputOption();// 增加向量之间的分隔符,默认为逗号;addOption("splitCharacterVector","scv", "Vector split character,default is ','", ",");// 增加向量和标示的分隔符,默认为冒号;addOption("splitCharacterLabel","scl", "Vector and Label split character,default is ':'", ":");if (parseArguments(args) == null) {return -1;}Path input = getInputPath();Path output = getOutputPath();String scv=getOption("splitCharacterVector");String scl=getOption("splitCharacterLabel");Configuration conf=getConf();//    FileSystem.get(output.toUri(), conf).deleteOnExit(output);//如果输出存在,删除输出HadoopUtil.delete(conf, output);conf.set("SCV", scv);conf.set("SCL", scl);Job job=new Job(conf);job.setJobName("transform text to vector by input:"+input.getName());job.setJarByClass(TFText2VectorWritable.class); job.setInputFormatClass(TextInputFormat.class);job.setOutputFormatClass(SequenceFileOutputFormat.class);job.setMapperClass(TFMapper.class);job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(VectorWritable.class);job.setNumReduceTasks(0);job.setOutputKeyClass(Text.class);job.setOutputValueClass(VectorWritable.class);TextInputFormat.setInputPaths(job, input);SequenceFileOutputFormat.setOutputPath(job, output);if(job.waitForCompletion(true)){return 0;}return -1;}public static class TFMapper extends Mapper<LongWritable,Text,Text,VectorWritable>{private String SCV;private String SCL;/*** 初始化分隔符参数 */@Overridepublic void setup(Context ctx){SCV=ctx.getConfiguration().get("SCV");SCL=ctx.getConfiguration().get("SCL");}/*** 解析字符串,并输出* @throws InterruptedException * @throws IOException */@Overridepublic void map(LongWritable key,Text value,Context ctx) throws IOException, InterruptedException{String[] valueStr=value.toString().split(SCL);if(valueStr.length!=2){return;  // 没有两个说明解析错误,退出}String name=valueStr[1];String[] vector=valueStr[0].split(SCV);Vector v=new RandomAccessSparseVector(vector.length);for(int i=0;i<vector.length;i++){double item=0;try{item=Double.parseDouble(vector[i]);}catch(Exception e){return; // 如果不可以转换,说明输入数据有问题}v.setQuick(i, item);}NamedVector nv=new NamedVector(v,name);VectorWritable vw=new VectorWritable(nv);ctx.write(new Text(name), vw);}}
}

上面的代码只使用了Mapper对数据进行处理即可,把原始数据的Text格式使用分隔符进行解析输出<Text,VectorWritable>对应<标识,样本向量>,贝叶斯算法处理的数据格式是VectorWritable的,所以要进行转换。其中的解析符号是根据传入的参数进行设置的。如果要单独运行该类,传入的参数如下:

 

 

usage: <command> [Generic Options] [Job-Specific Options]
Generic Options:-archives <paths>              comma separated archives to be unarchivedon the compute machines.-conf <configuration file>     specify an application configuration file-D <property=value>            use value for given property-files <paths>                 comma separated files to be copied to themap reduce cluster-fs <local|namenode:port>      specify a namenode-jt <local|jobtracker:port>    specify a job tracker-libjars <paths>               comma separated jar files to include inthe classpath.-tokenCacheFile <tokensFile>   name of the file with the tokens
Job-Specific Options:                                                           --input (-i) input                                    Path to job input       directory.              --output (-o) output                                  The directory pathname  for output.             --splitCharacterVector (-scv) splitCharacterVector    Vector split            character,default is    ','                     --splitCharacterLabel (-scl) splitCharacterLabel      Vector and Label split  character,default is    ':'                     --help (-h)                                           Print out help          --tempDir tempDir                                     Intermediate output     directory               --startPhase startPhase                               First phase to run      --endPhase endPhase                                   Last phase to run 

其中-scv和-scl参数是自己加的,其他参考mahout中的AbstractJob的默认设置;

 

2.转换标识

这一步的主要操作是把输入文件的所有标识全部读取出来,然后进行转换,转换为数值型,代码如下:

 

package mahout.fansy.bayes;import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Text;
import org.apache.mahout.common.Pair;
import org.apache.mahout.common.iterator.sequencefile.PathFilters;
import org.apache.mahout.common.iterator.sequencefile.PathType;
import org.apache.mahout.common.iterator.sequencefile.SequenceFileDirIterable;import com.google.common.io.Closeables;public class WriteIndexLabel {/*** @param args* @throws IOException */public static void main(String[] args) throws IOException {String inputPath="hdfs://ubuntu:9000/user/mahout/output_bayes/part-m-00000";String labPath="hdfs://ubuntu:9000/user/mahout/output_bayes/index.bin";Configuration conf=new Configuration();conf.set("mapred.job.tracker", "ubuntu:9001");long t=writeLabelIndex(inputPath,labPath,conf);System.out.println(t);}/*** 从输入文件中读出全部标识,并加以转换,然后写入文件* @param inputPath* @param labPath* @param conf* @return* @throws IOException*/public static long writeLabelIndex(String inputPath,String labPath,Configuration conf) throws IOException{long labelSize=0;Path p=new Path(inputPath);Path lPath=new Path(labPath);SequenceFileDirIterable<Text, IntWritable> iterable =new SequenceFileDirIterable<Text, IntWritable>(p, PathType.LIST, PathFilters.logsCRCFilter(), conf);labelSize = writeLabel(conf, lPath, iterable);return labelSize;}/*** 把数字和标识的映射写入文件* @param conf* @param indexPath* @param labels* @return* @throws IOException*/public static long writeLabel(Configuration conf,Path indexPath,Iterable<Pair<Text,IntWritable>> labels) throws IOException{FileSystem fs = FileSystem.get(indexPath.toUri(), conf);SequenceFile.Writer writer = new SequenceFile.Writer(fs, conf, indexPath, Text.class, IntWritable.class);Collection<String> seen = new HashSet<String>();int i = 0;try {for (Object label : labels) {String theLabel = ((Pair<?,?>) label).getFirst().toString();if (!seen.contains(theLabel)) {writer.append(new Text(theLabel), new IntWritable(i++));seen.add(theLabel);}}} finally {Closeables.closeQuietly(writer);}System.out.println("labels number is : "+i);return i;}
}


这一步要返回一个参数,即标识的一共个数,用于后面的处理需要。

 

3. 获得贝叶斯模型属性值1:

这个相当于 TrainNaiveBayesJob的第一个prepareJob,本来是可以直接使用mahout中的mapper和reducer的,但是其中mapper关于key的解析和我使用的不同,所以解析也不同,所以这一步骤的mapper可以认为就是TrainNaiveBayesJob中第一个prepareJob的mapper,只是做了很少的修改。此步骤的代码如下:

 

package mahout.fansy.bayes;import java.io.IOException;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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.SequenceFileOutputFormat;
import org.apache.hadoop.util.ToolRunner;
import org.apache.mahout.classifier.naivebayes.BayesUtils;
import org.apache.mahout.common.AbstractJob;
import org.apache.mahout.common.HadoopUtil;
import org.apache.mahout.common.mapreduce.VectorSumReducer;
import org.apache.mahout.math.VectorWritable;
import org.apache.mahout.math.map.OpenObjectIntHashMap;
/*** 贝叶斯算法第一个job任务相当于 TrainNaiveBayesJob的第一个prepareJob* 只用修改Mapper即可,Reducer还用原来的* @author Administrator**/
public class BayesJob1 extends AbstractJob {/*** @param args* @throws Exception */public static void main(String[] args) throws Exception {ToolRunner.run(new Configuration(), new BayesJob1(),args);}@Overridepublic int run(String[] args) throws Exception {addInputOption();addOutputOption();addOption("labelIndex","li", "The path to store the label index in");if (parseArguments(args) == null) {return -1;}Path input = getInputPath();Path output = getOutputPath();String labelPath=getOption("labelIndex");Configuration conf=getConf();HadoopUtil.cacheFiles(new Path(labelPath), getConf());HadoopUtil.delete(conf, output);Job job=new Job(conf);job.setJobName("job1 get scoreFetureAndLabel by input:"+input.getName());job.setJarByClass(BayesJob1.class); job.setInputFormatClass(SequenceFileInputFormat.class);job.setOutputFormatClass(SequenceFileOutputFormat.class);job.setMapperClass(BJMapper.class);job.setMapOutputKeyClass(IntWritable.class);job.setMapOutputValueClass(VectorWritable.class);job.setCombinerClass(VectorSumReducer.class);job.setReducerClass(VectorSumReducer.class);job.setOutputKeyClass(IntWritable.class);job.setOutputValueClass(VectorWritable.class);SequenceFileInputFormat.setInputPaths(job, input);SequenceFileOutputFormat.setOutputPath(job, output);if(job.waitForCompletion(true)){return 0;}return -1;}/*** 自定义Mapper,只是解析的地方有改动而已* @author Administrator**/public static class BJMapper extends Mapper<Text, VectorWritable, IntWritable, VectorWritable>{public enum Counter { SKIPPED_INSTANCES }private OpenObjectIntHashMap<String> labelIndex;@Overrideprotected void setup(Context ctx) throws IOException, InterruptedException {super.setup(ctx);labelIndex = BayesUtils.readIndexFromCache(ctx.getConfiguration()); //}@Overrideprotected void map(Text labelText, VectorWritable instance, Context ctx) throws IOException, InterruptedException {String label = labelText.toString(); if (labelIndex.containsKey(label)) {ctx.write(new IntWritable(labelIndex.get(label)), instance);} else {ctx.getCounter(Counter.SKIPPED_INSTANCES).increment(1);}}}}

如果要单独使用此类,可以参考下面的调用方式:

 

 

usage: <command> [Generic Options] [Job-Specific Options]
Generic Options:-archives <paths>              comma separated archives to be unarchivedon the compute machines.-conf <configuration file>     specify an application configuration file-D <property=value>            use value for given property-files <paths>                 comma separated files to be copied to themap reduce cluster-fs <local|namenode:port>      specify a namenode-jt <local|jobtracker:port>    specify a job tracker-libjars <paths>               comma separated jar files to include inthe classpath.-tokenCacheFile <tokensFile>   name of the file with the tokens
Job-Specific Options:                                                           --input (-i) input               Path to job input directory.                 --output (-o) output             The directory pathname for output.           --labelIndex (-li) labelIndex    The path to store the label index in         --help (-h)                      Print out help                               --tempDir tempDir                Intermediate output directory                --startPhase startPhase          First phase to run                           --endPhase endPhase              Last phase to run 

其中的-li参数是自己加的,其实就是第2步骤中求得的标识的总个数,其他参考AbstractJob默认参数。

 

 


分享,成长,快乐

转载请注明blog地址:http://blog.csdn.net/fansy1990



转载于:https://www.cnblogs.com/pangblog/p/3323104.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/274020.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java线程之多线程与多进程(3)——Java中的多线程

单线程 任何程序至少有一个线程&#xff0c;即使你没有主动地创建线程&#xff0c;程序从一开始执行就有一个默认的线程&#xff0c;被称为主线程&#xff0c;只有一个线程的程序称为单线程程序。如下面这一简单的代码&#xff0c;没有显示地创建一个线程&#xff0c;程序从mai…

几种常用控件的使用方法

1.UIActivityIndicatorView的使用 UIActivityIndicatorView *activity[[[UIActivityIndicatorViewalloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]autorelease]; z [activity setFrame:CGRectMake(150,150, 50, 50)]; [self.window addSubview:activ…

Java-正则表达式

什么是正则表达式&#xff1f; 正则表达式(Regular Expression)就是用某种模式去匹配一类字符串的公式。如你要在一篇文章中查找第一个字是“李”最后一个字是“建”的三个字的姓名&#xff0c;即“李*建”&#xff1b;那么“李*建”就是公式&#xff0c;也称作模式(Pattern)&a…

tab标签的另一种写法

<div class"good"><ul><li><span>歌曲精选</span></li><li class"other"><span>MV精选</span></li></ul><div class"music_good"><p><span>丁当</span…

java 中 if与while的区别

if&#xff1a;就是一个判断的&#xff0c;如果满足后面的条件就继续运行if语句里面的东西的&#xff0c;要是不满足就跳出来&#xff0c;执行else语句或执行下面的语句的 。while&#xff1a;就是循环语句的&#xff0c;当满足while里面的条件时&#xff0c;就会执行里面的循环…

install yael on the ubuntu 12.04

1. bits/predefs.h no such file or directory ??? sudo apt-get install gcc-multilib 2. sudo gedit /etc/profile PATH$PATH:/usr/local/MATLAB/R2012a/bin source /etc/profile 3.ubuntu 切换gcc 版本 1&#xff09;sudo apt-get install gcc-4.4 g-4.4 g-4.4-multi…

Java 线程多线程编程3---线程同步之生产者与消费者问题

生产者与消费者问题&#xff1a; 第一步&#xff1a;把架子搭起来 package com.zhj.www;public class ProceduerConsumer {public static void main(String[] args) {} }//馒头实体 class wotou{int id;wotou(int id) {this.id id;}public String toString() {return "wo…

windows 服务实例

参考来源:http://blog.csdn.net/morewindows/article/details/6858216 参考来源: http://hi.baidu.com/tfantasy/item/aefa43d66b470a2b38f6f76c 剩下的都是我自己整理的。 在VS2012中新建一个Windows 服务的项目。然后在解决方案目录下找到Services1.cs&#xff0c;切换到代码…

Java 线程多线程编程2---线程同步

来模拟一个死锁&#xff08;互相等待&#xff09;&#xff1a; TestDeadLock.java package com.zhj.www;public class TestDeadLock implements Runnable {public int flag 1;static Object o1 new Object();static Object o2 new Object();public void run() {System.out.p…

Java网络编程1---基础

TCP/IP:事实上的标准 自己编的应用程序&#xff1a;应用层 TCP/UDP层 IP层 物理层 数据封装&#xff1a;第五层只与第四层打交道。 数据拆封《TCP/IP详解》网络底层 IP巨大的贡献&#xff1a;提供了独一无二的IP地址。 内网IP&#xff1a;虚假的 子网掩码&#xff1a;255.255.2…

Java网络编程2---Socket-TCP编程

Sockct:插座Socket是关于TCP的。 端口号&#xff1a;两个字节->65536个端口号&#xff0c;一个应用程序占多个端口号&#xff1b; 但是假设一个应用程序占一个端口号&#xff1b;一台电脑会有65535个应用程序。 自己编写程序要占用端口号1024以上后的。 80端口&#xff1a;网…

winform绑定多张图片

开发winform程序的时候经常设计到要显示多张图片的问题&#xff0c;其解决思路一般是先遍历文件夹中的所有图片&#xff0c;然后再把这些图片添加到ImageList控件中&#xff0c;最后再绑定显示出来。这里我们介绍两种绑定的方法&#xff1a; &#xff08;一&#xff09;动态生成…

Java网络编程3---Socket-UDP编程

栗子&#xff1a;TestUDPServer.java 服务器端&#xff1a; package com.zhj.www;import java.net.DatagramPacket; import java.net.DatagramSocket;public class TestUDPServer {public static void main(String[] args)throws Exception {byte buf[] new byte[1024];Datagr…

iOS 6 自动布局入门

http://www.raywenderlich.com/zh-hans/22873/ios-6-自动布局-入门&#xff0d;1转载于:https://www.cnblogs.com/ihojin/p/auto-layout.html

Java GUI 基础知识

这部分主要包含AWT、组件和容器、布局管理器Component&#xff1a;所有可以和用户交互的图形元素&#xff0c;他的子类有&#xff1a;输入框… Java.awt及其子包 Container&#xff1a;容器&#xff0c;容纳其他各种各样的Component的元素。 Panel&#xff1a;可以容纳其他元素…

UVA11300

初步解题原理:代数运算单元素极值 代数运算: xi表示第i个给i-1的数量&#xff0c;正负表示给或得 c(a1a2a3....an)/n a1-x1x2c -->x2x1-a1c a2-x2x3c -->x3x1-a1-a22c a3-x3x4c -->x4x1-a1-a2-a33c ...... an-xnx1c -->xnx1-a1-a2-a3....-a(n-1)(n-1)c ansmax{|x1|…

Java GUI 基础知识2 监听机制

TestActionEvent.java没有调用方法&#xff0c;但是有反应。反应自己要编写程序有反应。 事件模型&#xff1a;一定要有某些反应。 写程序&#xff0c;监听的操作是自动发生的&#xff0c;一直监听。钩子函数&#xff0c;&#xff08;回调函数&#xff09; 怎么让它自动执行&am…

求字符串的最长回文字串 O(n)

昨天参加了某公司的校园招聘的笔试题&#xff0c;做得惨不忍睹&#xff0c;其中就有这么一道算法设计题&#xff1a;求一个字符串的最长回文字串。我在ACM校队选拔赛上遇到过这道题&#xff0c;当时用的后缀数组AC的&#xff0c;但是模板忘了没写出代码来。 回头我把这道题目再…

数据结构 二、向量(接口与实现and可扩容向量)

ADT操作实例&#xff1a;Disordered&#xff1a;显示出3对逆序紧邻对。Vector模板类初始有效空间为0&#xff1b;基于复制的构造描述区间&#xff1a;左闭右开 为什么*2&#xff1f;有限时间内不必要为扩容而打断。 2、可扩充向量左移一位&#xff1a;加一倍

数据库:mysql 获取刚插入行id[转]

我们在写数据库程序的时候,经常会需要获取某个表中的最大序号数, 一般情况下获取刚插入的数据的id&#xff0c;使用select max(id) from table 是可以的。但在多线程情况下&#xff0c;就不行了。 下面介绍三种方法 (1) getGeneratedKeys()方法: 程序片断: Connection conn ; …