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

原文:http://xiaoxia.org/2011/12/18/map-reduce-program-of-rmm-word-count-on-hadoop/

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

我知道这个文章标题很“学术”化,很俗,让人看起来是一篇很牛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 plaincopy to clipboardprint?
  1. #!/usr/bin/env python  
  2. from smallseg import SEG  
  3. import sys  
  4. seg = SEG()  
  5.   
  6. for line in sys.stdin:  
  7.     wlist = seg.cut(line.strip())  
  8.     for word in wlist:  
  9.         try:  
  10.             print "%s\t1" % (word.encode("utf8"))  
  11.         except:  
  12.             pass  

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

单词[tab]1

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

Reducer程序

下面是reducer.py的代码.

view plaincopy to clipboardprint?
  1. #!/usr/bin/env python  
  2. import sys  
  3. current_word,current_count,word = None, 1, None  
  4.   
  5. for line in sys.stdin:  
  6.     try:   
  7.         line = line.rstrip()  
  8.         word, count = line.split("\t", 1)  
  9.         count = int(count)  
  10.     except: continue  
  11.       
  12.     if current_word == word:  
  13.         current_count += count  
  14.     else:  
  15.         if current_word:  
  16.             print "%s\t%u" % (current_word, current_count)  
  17.         current_count, current_word = count, word  
  18.           
  19. if 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
龟裂    1
hadoop@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 > sorted
hadoop@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 进行简单的并行计算的实现。我们也对并行算法和串行算法的区别和设计有了更深一层的了解。此外,实验还增进了我们的合作精神,提高了我们的动手能力。

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

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

相关文章

Web服务的调用

1、创建服务引用 例如:天气预报 2、在代码添加引用空间 TvProgram.ChinaTVprogramWebService tpnew TvProgram.ChinaTVprogramWebService(); DataSet dstp.getAreaDataSet();3、引用具体方法 private void comBox1_SelectedIndexChanged(object sender,EventArgs e)…

aref无效 lisp_aref无效 lisp_Common Lisp专题4:数组

1)用make-array创建数组:CL-USER> (make-array 5 :initial-element nil)#(NIL NIL NIL NIL NIL)CL-USER> (make-array 5 :initial-contents (a e i o u))#(A E I O U)CL-USER> (setf arr (make-array 5 :initial-contents (a e i o u)))#(A E I O U)CL-USE…

Visual Studio 快捷键汇总

常见方法: 强迫智能感知:CtrlJ。智能感知是Visual Studio最大的亮点之一,选择Visual Studio恐怕不会没有这个原因。 撤销:CtrlZ。除非你是天才,那么这个快捷键也是最常用的。强迫显示参数信息:Ctrl-Shift-空…

nodejs解析apk

项目再github上的目录:https://github.com/chen2009277025/nodejs_apkToolnodejs无可厚非是新兴的后端语言,因为他的开发语言是javascript,javascript语言的自身优势,让nodejs迅速的火遍大江南北。很多的nodejs的开发插件如雨后春…

VC2013 代码图,依赖项关系图,等出错解决办法.

环境WIN10VS2013SQL2015 当VS2013代码图,依赖项关系图等出现 数据库连接错误时 去http://www.microsoft.com/zh-cn/download/details.aspx?id29062 下载 SqlLocalDB.MSI进行安装 怀疑是先装了SQL2015后安装VS2013时默认未安装SqlLocalDB.MSI导致.转载于:https://www.cnblogs.c…

POJ 1330 LCA最近公共祖先 离线tarjan算法

题意要求一棵树上,两个点的最近公共祖先 即LCA 现学了一下LCA-Tarjan算法,还挺好理解的,这是个离线的算法,先把询问存贮起来,在一遍dfs过程中,找到了对应的询问点,即可输出 原理用了并查集和dfs…

deferred Transports Protocols 简单介绍

2019独角兽企业重金招聘Python工程师标准>>> Twisted架构概览 Twisted是一个事件驱动型的网络引擎。由于事件驱动编程模型在Twisted的设计哲学中占有重要的地位,因此这里有必要花点时间来回顾一下究竟事件驱动意味着什么。 事件驱动编程是一种编程范式&a…

java web 请求跟踪_IT兄弟连 JavaWeb教程 Servlet会话跟踪 Cookie技术

原标题:IT兄弟连 JavaWeb教程 Servlet会话跟踪 Cookie技术Cookie使用HTTPHeader传递数据。Cookie机制定义了两种报头,Set-Cookie报头和Cookie报头。Set-Cookie报头包含于Web服务器的响应头(ResponseHeader)中,Cookie报头包含在浏览器客户端请…

FAT和EXFAT文件系统

源:FAT和EXFAT文件系统转载于:https://www.cnblogs.com/LittleTiger/p/8022450.html

关于easyUI在子页面增加显示tabs的一个问题

关于easyUI在子 在父页面点个链接能动态看到子页面的情况太简单,请看easyUI官网:http://www.jeasyui.com/tutorial/layout/tabs2.php 现在说的是在子页面点个按钮也能触发增加子页面的情况。 情景是,在父页面上有个div如: Html代…

java 两个窗口 贴_粘贴子窗体中的多个记录时的子窗体校准错误

我对子窗体上的所有三个事件进行计算以更新主窗体:Private Sub Form_AfterDelConfirm(Status As Integer)Me.Parent.UpdateStundenEnd SubPrivate Sub Form_AfterInsert()Me.Parent.UpdateStundenEnd SubPrivate Sub Form_AfterUpdate()Me.Parent.UpdateStundenEnd …

SDN第二次上机作业

1、安装floodlight 2、生成拓扑并连接控制器floodlight,利用控制器floodlight查看图形拓扑 3、利用字符界面下发流表,使得‘h1’和‘h2’ ping 不通 4、利用字符界面下发流表,通过测试‘h1’和‘h3’的联通性,来验证openflow的har…

Android保存图片到本地相册

好久没有写东西了。备份下知识吧。免得忘记了 。 首先贴一段代码 -- 这个是先生成一个本地的路径,将图片保存到这个文件中,然后扫描下sd卡。让系统相册重新加载下 。缺点就是只能保存到DCIM的文 件夹下边,暂时不知道怎…

PHP的钩子实现解析

2019独角兽企业重金招聘Python工程师标准>>> 钩子是编程里一个常见概念,非常的重要。它使得系统变得非常容易拓展,(而不用理解其内部的实现机理,这样可以减少很多工作量)。只要有一个钩子样本,能…

writer在java中的意思_Java在FileWriter和BufferedWriter之间的区别

小编典典如果您使用BufferedWriter则效率更高在刷新/关闭之间有多次写入与缓冲区大小相比,写操作较小。在您的示例中,您只有一次写入,因此BufferedWriter只会增加您不需要的开销。这是否意味着第一个示例一个接一个地写入字符,第二…

Ubuntu配置静态IP

进入 /etc/network/interfaces,修改成如下: # interfaces(5) file used by ifup(8) and ifdown(8)auto loiface lo inet loopbackauto ens33iface ens33 inet staticaddress 192.168.1.110netmask 255.255.255.0gateway 192.168.1.1dns-nameserver 8.8.8…

tiny xml 使用总结

这几天在埋头写自己的3D文件浏览器(稍后发布),突发奇想的要把自己的内部格式转化成XML,于是,把以前在研究所时用过的ExPat翻了出来。ExPat是基于事件的XML解释器,速度挺快的,但结构方面有点不敢…

Beta冲刺! Day2 - 砍柴

Beta冲刺! Day2 - 砍柴 今日已完成 晨瑶:大致确定了文章推荐的算法思路(Content-based recommender);理清了不少feature的事宜昭锡:修复了日期选择越界时导致程序崩溃和点击光点返回后,日期选择…

Android版添加phonegap--websocket客户端插件教程

2019独角兽企业重金招聘Python工程师标准>>> 1.在Eclipse中新建Android Project项目chatdemo2.把animesh kumar的websocket-android-phonegap项目java文件打成phonegap-websocket-support.jar包,存放在 android project的libs目录下3.把websocket.js存放…

java参数传入的是一个类名_Java编程细节——泛型的定义(类、接口、对象)、使用、继承...

1. 设计泛型的初衷:1) 主要是为了解决Java容器无法记忆元素类型的问题:i. 由于Java设计之初并不知道会往容器中存放什么类型的元素,因此元素类型都设定为Object,这样就什么东西都能放了!ii. 但是这样设计有明显的缺点&…