内容简介:你知道著名武侠小说《天龙八部》里哪个人物名字出现的次数最多?可能你会说是乔峰,这是真的吗?让我们用 HadoopMapReduce 的词频分析来做验证吧。本课程是 Hadoop 的一个非常基础的应用项目,利用实验楼提供的 Hadoop 环境,对一本武侠小说的文集进行简单的课程设计部分内容及代码参考了
基于 Hadoop 对武侠小说进行词频分析
一、实验介绍
1.1 实验内容
你知道著名武侠小说《天龙八部》里哪个人物名字出现的次数最多?可能你会说是乔峰,这是真的吗?让我们用 HadoopMapReduce 的词频分析来做验证吧。
本课程是 Hadoop 的一个非常基础的应用项目,利用实验楼提供的 Hadoop 环境,对一本武侠小说的文集进行简单的 WordCount
词频统计,从而得到该书中出现频次最高的人名。
课程设计部分内容及代码参考了 在 Hadoop 上运行基于 RMM 中文分词算法的 MapReduce 程序 这篇文章,以及结巴分词 的文档。
实验过程中可以参考文档中提供的完整代码,一步步按照文档介绍完成整个操作过程,从而对 Hadoop 的基本操作及进行词频统计的方法进行学习。
1.2. 实验知识点
本课程完成后,希望在动手实践的过程中,能够达到如下几点实验目标:
1.3 实验环境
本课程实验环境使用实验楼提供的 Ubuntu 14.04
64位操作系统,其中安装有 Hadoop 2.6.0
版本,需要使用 su -l hadoop
切换到 hadoop
用户使用,切换过程中需要输入 hadoop
用户的密码: hadoop
,默认登录的 shiyanlou 用户无法直接使用 Hadoop。
如果您对 Linux 实验环境不熟悉,推荐您先学习《新手入门之玩转实验楼》。
1.4 适合用户
本课程难度为简单,属于入门级别课程,适合对 Hadoop 刚刚入门的用户,甚至没有接触过 Hadoop 的用户也可以按照步骤一步步做出来。
1.5 代码获取
本实验所有代码可以使用 git clone
命令在 git 服务器下载:
$ git clone https://github.com/shiyanlou/hadoopwordcount
如果想在实验环境中下载代码,可以打开桌面上的 Xfce 终端
,然后输入命令 git clone https://github.com/shiyanlou/hadoopwordcount
进行获取。
如果想进一步了解 Git 命令及操作,可以学习免费教程《Git 实战教程》。
二、实验原理
本节主要讲解 Hadoop词频统计的原理。
实验中的代码将基于 Hadoop 的 Streaming 工作模式实现,Streaming 模式下 Hadoop 可以使用非 Java 编写的 MapReduce 程序。
MapReduce 是一种编程模型,适用于处理海量的数据,分为 Map(映射)和 Reduce(归约)两个步骤。 Mapper
函数将一组 key-value 对映射为一组新的 key-value,然后交给并发的 Reducer
函数。词频统计中,Mapper 接受的 key 是文件名称,值是文件的内容,使用分词后逐个遍历词,每遇到一个词就产生一个中间 key-value 对 (词,1)
,key 指的是词,value 是 1
,表示又找到了一个词。MapReduce 程序将 key 相同(同一个词)的 key-value 对传给 Reducer,这样 Reducer 接收了一系列同一 key 的 key-value 对,然后累加后得到该词出现的次数。最终将计算结果输出到 HDFS 文件系统。
程序运行的步骤如下所示:
- 输入《天龙八部》文本文件。
- 将输入文件分成 N 片(N 为 Mapper 程序数量)。
- 将每一片内容分给一个 Mapper 程序进行计算。
- 每个 Mapper 程序计算后将生成的输出作为输入交给 Reducer 程序。
- 每个 Reducer 程序汇总 Mapper 的输入后各自输出一份结果。
三、开发准备
3.1 安装分词工具
首先要做词频分析,需要安装中文分词的工具。分词的作用是将长句子中出现的中文词语进行切分,从文章中提取一个个中文词语。
实验中我们选择 Python 语言编写 MapReduce 程序,为了快速实现分词过程,Python 分词 工具 选择优秀的结巴分词。
打开桌面上的 Xfce 终端
,目前的默认用户是 shiyanlou
用户,输入下面的 pip
命令安装 jieba 分词,为了加快下载速度,我们使用的是豆瓣的 pip 安装源:
$ sudo pip install -i http://pypi.douban.com/simple/ jieba
操作截图:
3.2 切换到 hadoop 用户
打开 Xfce 终端,输入截图中所示的命令 su -l hadoop
,需要输入 hadoop 用户的密码 hadoop
(注意:Linux 上切换用户输入密码是不显示的)
3.3 下载输入文件
《天龙八部》文件可以从网上下载,文件仅用于测试学习,将会随实验结束销毁。使用下述 wget
命令 下载测试的武侠小说文件:
$ wget http://labfile.oss.aliyuncs.com/hadoop/tlbbtestfile.txt
切换用户及下载测试文件的操作截图:
3.4 添加文件到 HDFS
首先实验楼环境中默认提供的 Hadoop 2.6.0,首先需要配置环境变量,让我们在实验楼的环境中可以使用这个版本的 Hadoop,将 Hadoop 2.6.0 的路径添加到 PATH 中,需要执行下面的命令(此时已经切换到 hadoop 用户):
$ export PATH=$PATH:/opt/hadoop-2.6.0/bin:/opt/hadoop-2.6.0/sbin
注意:Hadoop 的目录在 /opt/hadoop-2.6.0
此时可以直接使用 hadoop version
查看 Hadoop 版本:
使用 Hadoop 的 hdfs 命令将刚刚下载的文件添加到 HDFS,并重命名为 testinput.txt:
$ hdfs dfs -put tlbbtestfile.txt testinput.txt
四、实验步骤
4.1 程序编写
在 /home/hadoop
目录下创建 hadoopwordcount
文件夹及 mapper.py
和 reducer.py
文件,注意两个文件需要把权限设置为可执行,使用 hadoop 用户在终端中依次执行下面的命令,每个命令的说明见命令上方的注释信息:
# 进入到 hadoop 用户的家目录 $ cd /home/hadoop # 创建代码文件夹 $ mkdir hadoopwordcount # 创建 Mapper 程序文件 $ touch hadoopwordcount/mapper.py # 创建 Reducer 程序文件 $ touch hadoopwordcount/reducer.py # 给所有 Python 脚本增加可执行权限 $ chmod a+x hadoopwordcount/*.py
4.1.1 mapper 程序
注意:编辑代码文件推荐使用 vim,桌面上的 gedit 因为启动是 shiyanlou 用户,不具备编辑 hadoop 用户目录下文件的权限。
首先我们实现 Mapper 程序,Mapper 程序的作用就是:
- 从 stdin 标准输入中依次读取每一行。
- 对每一行使用 jieba 分词进行分词。
- 对分词得到的词汇列表进行 Map 操作:每个词都映射成(word,1)这样的二元组,并输出到标准输出 stdout 中。
这个程序较简单,请尽量按照上述的逻辑描述自己实现。下方提供了详细的代码实现和注释信息,以供参考:
#!/usr/bin/env python # 引入 jieba 分词模块 import jieba import sys # 从 stdin 标准输入中依次读取每一行 for line in sys.stdin: # 对每一行使用 jieba 分词进行分词 wlist = jieba.cut(line.strip()) # 对分词得到的词汇列表进行 Map 操作 for word in wlist: try: # 每个词都映射成(word,1)这样的二元组 # 输出到标准输出 stdout 中 print "%s\t1" % (word.encode("utf8")) except: pass
4.1.2 reducer 程序
Reducer 程序比 Mapper 要复杂些,基本逻辑如下步骤:
- 从标准输入读取单词和词频。
- 对每个词出现的频次进行叠加,直到不再出现该词。
- 输出词和词频。
参考代码和注释信息如下:
#!/usr/bin/env python import sys # 定义临时变量存储中间数据 current_word, current_count, word=None,1,None # 依次从标准输入读取每一行 for line in sys.stdin: try: # 每一行都是一个(word,count)的二元组,从中提取信息词语和数量 line = line.rstrip() word, count = line.split("\t", 1) count = int(count) except: continue # 判断当前处理的词是从当前行提取的词 if current_word == word: # 如果是,则增加当前处理的词出现的频次 current_count += count else: # 如果不是,则需要输出当前处理的词和词频到标准输出 if current_word: print "%s\t%u" % (current_word, current_count) current_count, current_word = count, word # 读取完毕后需要处理当前词是读取词,但没有输出的情况 if current_word == word: print "%s\t%u" % (current_word, current_count)
4.2 运行 MapReduce
4.2.1 运行命令
命令中我们使用到了 Hadoop streaming 来运行 python 程序,并指定 mapper 和 reducer 程序及输入文件的位置,同时运行了4个 mapper 实例和2个 reducer 实例。
需要运行的命令如下:
$ hadoop jar /opt/hadoop-2.6.0/share/hadoop/tools/lib/hadoop-streaming-2.6.0.jar -mapper /home/hadoop/hadoopwordcount/mapper.py -reducer /home/hadoop/hadoopwordcount/reducer.py -input testinput.txt -output wordcountout -jobconf mapred.map.tasks=4 -jobconf mapred.reduce.tasks=2
由于实验楼的环境比较慢,所以我们可以慢慢查看整个 MapReduce 的过程,一直到最后输出结果。
过程中的截图如下所示。如果感兴趣的话,可以分析下每条日志信息。
4.2.2 成功后的结果
4.3 查看结果
4.3.1 将结果从 HDFS 导出
虽然我们使用的 Hadoop 是单机模式,结果文件直接存放在 /home/hadoop
目录,但我们也需要了解下如何从一个真正的 HDFS 系统中导出结果。
使用下面的命令可以从 HDFS 导出文件到指定的目录 /tmp/output
:
$ mkdir /tmp/output $ hdfs dfs -get wordcountout/part-0000* /tmp/output $ ls /tmp/output/
导出及查看文件列表:
4.3.2 处理输出文件
两个 reducer 得到两个输出文件 part-00000
和 part-00001
,对输出的处理将按照下面的步骤进行:
awk sort head
整个操作过程如下图所示,每个命令的详细参数可以查看 man
文档获得,在此不再赘述:
结果是不是很显而易见了?段誉的出镜率最高,不过不要过早下结论,思考下萧峰还有个名字叫乔峰,如果这两个名字的频率加起来是不是会超过段誉呢?答案需要你自己去实验揭晓了。实验中有任何问题欢迎到讨论区 提问。
五、实验总结
词频统计是 Hadoop 最基本的一个应用。通过这个简单的应用熟悉 MapReduce 的原理,及 Python 实现 MapReduce 程序的方法。有兴趣的同学可以找其他的文档( 需要注意 UTF8 的编码问题 )来进行词频检测,也可以扩展改写当前的程序实现其他应用,比如每个章节的主角都分别是谁?
实验中有任何问题欢迎到讨论区 提问。
六、课后习题
那么,根据你的实验结果,在《天龙八部》中,是段誉的出现频次高还是乔峰(萧峰)呢?
可以将截图和实验过程写入实验报告,并发布到讨论区 跟同学们一起交流。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。