Hadoop 实战之分析专利引用数据集(三)

大家好,今天我们在Hadoop 实战之分析专利引用数据集(一)的基础上来实现计算专利被引用的次数

许多外行人认为统计学就是数量统计,并且许多基本的Hadoop Job就是用于统计数量的。我们已经在第一章中看过统计单词个数的例子了。对于那些专利引用数据,我们可能想要知道专利被引用的次数。这也是一种数量统计。我们期望得到如下形式的结果:

1 2  
10000 1  
100000 1  
1000006 1  
1000007 1  
1000011 1  
1000017 1  
1000026 1  
1000033 2  
1000043 1  
1000044 2  
1000045 1  
1000046 2  
1000049 1  
1000051 1  
1000054 1  
1000065 1  
1000067 3
 在每条记录中,专利号与它被引用的次数关联。我们可以编写MapReduce程序来执行这项任务。就像我们之前说的那样,您几乎不会重头编写一个MapReduce程序。您已经有了一个以类似的方式处理数据的MapReduce程序。您需要复制并修改它,直到符合您的要求。
  我们之前写过一个以相反的次序显示引用记录的程序。我们可以使程序显示引用次数,而不是引用的专利的列表。我们需要修改Reducer。如果我们选择将引用次数作为IntWritable,我们需要在Reducer代码中的三个地方指定IntWritable。我们在前置注解中将它们称为V3。

    public static class Reduce extends MapReduceBase implements  
            Reducer<Text, Text, Text, IntWritable> {  
        public void reduce(Text key, Iterator<Text> values,  
                OutputCollector<Text, IntWritable> output, Reporter reporter)  
                throws IOException {  
            int count = 0;  
            while (values.hasNext()) {  
                values.next();  
                count++;  
            }  
            output.collect(key, new IntWritable(count));  
        }  
    } 
 通过修改少量的代码行来与类型匹配,我们获得了一个新的MapReduce程序。这个程序看起来只有很小的改动,让我们看看另一个需要更多改动的例子,您会发现它仍然会保留基本的MapReduce程序的结构。
  在运行之前的例子之后,我们现在有了统计每个专利被引用的次数的数据。一个有趣的练习是对统计结果进行计数。我们预期大量的专利可能只会被引用一次,而少数的专利将会被引用几百次。观察引用次数的分布是一件有趣的事情。

编写MapReduce程序的第一步是弄清楚数据流。在这种情况下,mapper读取记录时,忽略了专利号,并输出中间键/值对<citation_count, 1>。reducer会将每个引用计数加1,并将总数输出。
  在弄清楚数据流之后,需要决定键值对的类型——K1、V1,K2、 V2, K3和V3,分别用于输入、中间结果和输出键/值对。我们将使用KeyValueTextInputFormat类型,它将自动地将每个输入记录分解为基于分隔符的键/值对。输出格式将K1和V1作为文本进行处理。我们选择IntWritable类作为K2、V2、K3和V3的类型,因为我们知道那些数据肯定是整数,并且使用IntWritable的性能更好。

环境:Vmware 8.0 和Ubuntu11.04

Hadoop 实战之分析专利引用数据集(三)---从专利引用数据集中计算专利被引用的次数

第一步:首先创建一个工程命名为HadoopTest.目录结构如下图:


第二步: 在/home/tanglg1987目录下新建一个start.sh脚本文件,每次启动虚拟机都要删除/tmp目录下的全部文件,重新格式化namenode,代码如下:
sudo rm -rf /tmp/*
rm -rf /home/tanglg1987/hadoop-0.20.2/logs
hadoop namenode -format
hadoop datanode -format
start-all.sh
hadoop fs -mkdir input 
hadoop dfsadmin -safemode leave

第三步:给start.sh增加执行权限并启动hadoop伪分布式集群,代码如下:

chmod 777 /home/tanglg1987/start.sh
./start.sh 

执行过程如下:

第四步:上传本地文件到hdfs

在专利局http://data.nber.org/patents/网站下载专利数据

http://data.nber.org/patents/apat63_99.zip

hadoop fs -put /home/tanglg1987/cite75_99.txt input

五步:新建一个MyJob3.java,代码如下:

package com.baison.action;
import java.io.IOException;
import java.util.Iterator;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.FileInputFormat;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.hadoop.mapred.JobClient;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.KeyValueTextInputFormat;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reducer;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class MyJob3 extends Configured implements Tool {   
    public static class MapClass extends MapReduceBase
        implements Mapper<Text, Text, Text, Text> {      
        public void map(Text key, Text value,
                        OutputCollector<Text, Text> output,
                        Reporter reporter) throws IOException {                       
            output.collect(value, key);
        }
    }   
    public static class Reduce extends MapReduceBase
        implements Reducer<Text, Text, Text, IntWritable> {     
        public void reduce(Text key, Iterator<Text> values,
                           OutputCollector<Text, IntWritable> output,
                           Reporter reporter) throws IOException {                        
            String csv = "";
            int count=0;   
            while (values.hasNext()) {
                if (csv.length() > 0) csv += ",";
                csv += values.next().toString();
                count++;
            }
            output.collect(key, new IntWritable(count));
        }
    }
    
    public int run(String[] args) throws Exception {
    	for (String string : args) {
			System.out.println(string);
		}
        Configuration conf = getConf();    
        JobConf job = new JobConf(conf, MyJob3.class);    
        Path in = new Path(args[0]);
        Path out = new Path(args[1]);
        FileInputFormat.setInputPaths(job, in);
        FileOutputFormat.setOutputPath(job, out);      
        job.setJobName("MyJob");
        job.setMapperClass(MapClass.class);
        job.setReducerClass(Reduce.class);    
        job.setInputFormat(KeyValueTextInputFormat.class);
        job.setOutputFormat(TextOutputFormat.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        job.set("key.value.separator.in.input.line", ",");      
        JobClient.runJob(job);      
        return 0;
    }
    
    public static void main(String[] args) throws Exception { 
    	String [] arg={"hdfs://localhost:9100/user/tanglg1987/input/cite75_99.txt","hdfs://localhost:9100/user/tanglg1987/output"};
        int res = ToolRunner.run(new Configuration(), new MyJob3(), arg);       
        System.exit(res);
    }
}

第六步:Run On Hadoop,运行过程如下:

hdfs://localhost:9100/user/tanglg1987/input/cite75_99.txt
hdfs://localhost:9100/user/tanglg1987/output
12/10/18 22:24:57 INFO jvm.JvmMetrics: Initializing JVM Metrics with processName=JobTracker, sessionId=
12/10/18 22:24:57 WARN mapred.JobClient: No job jar file set.  User classes may not be found. See JobConf(Class) or JobConf#setJar(String).
12/10/18 22:24:58 INFO mapred.FileInputFormat: Total input paths to process : 1
12/10/18 22:24:58 INFO mapred.JobClient: Running job: job_local_0001
12/10/18 22:24:58 INFO mapred.FileInputFormat: Total input paths to process : 1
12/10/18 22:24:58 INFO mapred.MapTask: numReduceTasks: 1
12/10/18 22:24:58 INFO mapred.MapTask: io.sort.mb = 100
12/10/18 22:24:58 INFO mapred.MapTask: data buffer = 79691776/99614720
12/10/18 22:24:58 INFO mapred.MapTask: record buffer = 262144/327680
12/10/18 22:24:59 INFO mapred.MapTask: Spilling

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值