在Hadoop上运行基于RMM中文分词算法的MapReduce程序

来源:互联网 发布:电信网络诈骗犯罪量刑 编辑:程序博客网 时间:2024/06/01 08:04
2人收藏此文章,我要收藏发表于3个月前 , 已有252次阅读 共0个评论

我知道这个文章标题很“学术”化,很俗,让人看起来是一篇很牛B或者很装逼的论文!其实不然,只是一份普通的实验报告,同时本文也不对RMM中文分 词算法进行研究。这个实验报告是我做高性能计算课程的实验里提交的。所以,下面的内容是从我的实验报告里摘录出来的,当作是我学习hadoop分享出来的 一些个人经验。

实验目标

学习编写 Hadoop 上的 MapReduce 程序。
使用 Hadoop 分布式计算小说《倚天屠龙记》里的中文单词频率,比较张无忌身边的两个女人周芷若与赵敏谁在小说里的热度高。(为什么要提到倚天屠龙记呢?因为我的一位舍 友最近把贾静雯演的这部戏看完了,他无时无刻不提到贾静雯演的赵敏,所以这个实验也取材自我的大学生活……)

实验原理

通过自学Hadoop的Streaming工作模式,使用Streaming可以让Hadoop运行非Java的MapReduce程序。

为了减少我们的实验时间,我们使用了以开发效率著名的Python语言来编写我们的mapper.py和reducer.py。其中,我们还使用到 了一个小巧的中文分词模块smallseg.py,引用自(http://code.google.com/p/smallseg/,Apache License 2.0)。

对于中文词库,我们使用搜狗实验室提供的中文词库main.dic以及一个字库suffix.dic,均可从smallseg项目中获得。

分布式计算的输入为一个文本文件:倚天屠龙记.txt,我们从网下下载此文本资源,并且转换为utf8文本编码以方便我们在Linux下进行分词计算。

iconv -fgbk -tutf8 倚天屠龙记.txt > 倚天屠龙记utf8.txt

实验环境

NameNode:
OS: Ubuntu11.04
CPU: Intel Core I3
Memory: 512MB
IP: 125.216.244.28

DataNode1:
OS: Ubuntu11.10
CPU: Intel Pentium 4
Memory: 512MB
IP: 125.216.244.21

DataNode2:
OS: Ubuntu11.10
CPU: Intel Pentium 4
Memory: 512MB
IP: 125.216.244.22

Mapper程序

下面是mapper.py的代码。

    view source
    print?
    01#!/usr/bin/env python
    02from smallseg import SEG
    03import sys
    04seg =SEG()
    05  
    06for line in sys.stdin:
    07    wlist= seg.cut(line.strip())
    08    forword in wlist:
    09        try:
    10            print"%s\t1" % (word.encode("utf8"))
    11        except:
    12            pass

      smallseg为一个使用RMM字符串分割算法的中文分词模块。Mapper程序的过程很简单,对每一行的中文内容进行分词,然后把结果以单词和频率的格式输出。对于所有的中文单词,都是下面的格式,

      单词[tab]1

      每个单词的频率都为1。Mapper并不统计每一行里的单词出现频率,我们把这个统计频率的工作交给Reducer程序。

      Reducer程序

      下面是reducer.py的代码.

      view source
      print?
      01#!/usr/bin/env python
      02import sys
      03current_word,current_count,word = None,1, None
      04  
      05for line in sys.stdin:
      06    try:
      07        line= line.rstrip()
      08        word, count= line.split("\t",1)
      09        count= int(count)
      10    except:continue
      11  
      12    ifcurrent_word ==word:
      13        current_count+=count
      14    else:
      15        ifcurrent_word:
      16            print"%s\t%u" %(current_word, current_count)
      17        current_count, current_word= count, word
      18  
      19if current_word ==word:
      20    print"%s\t%u" %(current_word, current_count)

      从标准输入中读取每一个单词频率,并且统计。因为这些单词已经由Hadoop为我们排好了顺序,所以我们只需要对一个单词的出现次数进行累加,当出现不同的单词的时候,我们就输出这个单词的频率,格式如下

      单词[tab]频率

      实验步骤

      实验使用一个NameNode节点和两个DataNode节点。
      首先,把所需要的文件复制到每一台主机上。这些文件都放在/home/hadoop/wc目录下。

      scp -r wc hadoop@125.216.244.21:.
      scp -r wc hadoop@125.216.244.22:.
      scp -r wc hadoop@125.216.244.28:.

      运行Hadoop Job

      本次任务,使用3个Mapper进程以及2个Reducer进程。因为分词的步骤最为耗时,所以我们尽量分配最多数目的Mapper进程。

      hadoop@xiaoxia-vz:~/hadoop-0.20.203.0$ ./bin/hadoop jar contrib/streaming/hadoop-streaming-0.20.203.0.jar -mapper /home/hadoop/wc/mapper.py -reducer /home/hadoop/wc/reducer.py -input 2-in -output 2-out -jobconf mapred.map.tasks=3 -jobconf mapred.reduce.tasks=2[...] WARN streaming.StreamJob: -jobconf option is deprecated, please use -D instead.packageJobJar: [/tmp/hadoop-unjar2897218480344074444/] [] /tmp/streamjob7946660914041373523.jar tmpDir=null[...] INFO mapred.FileInputFormat: Total input paths to process : 1[...] INFO streaming.StreamJob: getLocalDirs(): [/tmp/mapred/local][...] INFO streaming.StreamJob: Running job: job_201112041409_0005[...] INFO streaming.StreamJob: To kill this job, run:[...] INFO streaming.StreamJob: /home/hadoop/hadoop-0.20.203.0/bin/../bin/hadoop job  -Dmapred.job.tracker=http://125.216.244.28:9001 -kill job_201112041409_0005[...] INFO streaming.StreamJob: Tracking URL: http://localhost:50030/jobdetails.jsp?jobid=job_201112041409_0005[...] INFO streaming.StreamJob:  map 0%  reduce 0%[...] INFO streaming.StreamJob:  map 9%  reduce 0%[...] INFO streaming.StreamJob:  map 40%  reduce 0%[…] INFO streaming.StreamJob:  map 67%  reduce 12%[...] INFO streaming.StreamJob:  map 71%  reduce 22%[...] INFO streaming.StreamJob:  map 100%  reduce 28%[...] INFO streaming.StreamJob:  map 100%  reduce 100%[...] INFO streaming.StreamJob: Job complete: job_201112041409_0005[...] INFO streaming.StreamJob: Output: 2-out

      Map过程耗时:41s
      Reduce过程耗时:21s
      总耗时:62s

      计算结果

      复制计算结果到本地文件系统。

      ./bin/hadoop dfs -get 2-out/part* ../wc/

      查看part*的部分内容:

      hadoop@xiaoxia-vz:~/wc$ tail part-00000龙的    1龙眼    1龙虎    2龙被    1龙身    2龙镇    1龙骨    1龟寿    2龟山    1龟裂    1hadoop@xiaoxia-vz:~/wc$ tail part-00001龙门    85龙飞凤舞        1龙驾    1龟      3龟一    1龟二    1龟息    1龟缩    1龟蛇    3

      下面,对输出的结果进行合并,并按照频率进行排序。该过程比较快,在1秒内就已经完成。

      hadoop@xiaoxia-vz:~/wc$ cat part-00000 part-00001 | sort -rnk2,2 > sortedhadoop@xiaoxia-vz:~/wc$ head sorted的      7157张无忌  4373是      4199道      3465了      3187我      2516他      2454你      2318这      1991那      1776

      我们去掉单个字的干扰,因为我们的实验目的只对人名感兴趣。

      hadoop@xiaoxia-vz:~/wc$ cat sorted | awk '{if(length($1)>=4) print $0}' | head -n 50张无忌  4373说道    1584赵敏    1227谢逊    1173自己    1115甚么    1034张翠山  926武功    867一个    777咱们    767周芷若  756教主    739笑道    693明教    685一声    670听得    634姑娘    612师父    606只见    590无忌    576少林    555如此    547弟子    537之中    527殷素素  518杨逍    496他们    490不知    484如何    466我们    453两人    453叫道    450二人    445今日    443心想    433张三丰  425声道    425义父    412出来    402虽然    395灭绝师太        392之下    389这时    381莲舟    374心中    374便是    371不敢    371俞莲    369不能    359身子    356

      统计图表

      结论

      赵敏以1227票的频率完胜周芷若的756票,由此可知赵敏在《倚天屠龙记》里的热度比周芷若高。

      经过本次实验,我们对 Hadoop 原理有了一定程度的了解,并且顺利的完成Mapper函数和Reducer函数的设计和测试。能够运用 Hadoop 进行简单的并行计算的实现。我们也对并行算法和串行算法的区别和设计有了更深一层的了解。此外,实验还增进了我们的合作精神,提高了我们的动手能力。

      原创粉丝点击