徐宏博+趙文濤+孟令軍
摘要:中文分詞方法都屬于串行分詞方法,不能處理海量數(shù)據(jù)。提出一種基于MapReduce的并行分詞方法。Mapreduce編程模型默認(rèn)使用TextInputFormat文本輸入方式,該方式不適合處理大量文本文件。首先基于CombineFileInputFormat父類,自定義文本輸入方式MyInputFormat,并在實(shí)現(xiàn)createRecordReader方法過(guò)程中返回RecordReader對(duì)象。其次自定義MyRecordReader類來(lái)說(shuō)明讀取文本
關(guān)鍵詞:MapReduc;分片;TextInputFormat;CombineFileInputFormat
中圖分類號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2016)22-0171-05
Abstract: Method of word segmentation is a serial process and it fails to deal with big data. We put forward a parallel word segmentation based on MapReduce. TextInputFormat is the default input class when preprocessing in the programming model of Mapreduce, while it fails to process datasets which is made up of many small files. Firstly, we define a new class named MyInputFormat based on the class of CombineFileInputFormat,and return an object of RecordReader class. Secondly, we declare MyRecordReader class , by which can we write a new logic method to read and split the original data to
Key words: MapReduce; split; TextInputFormat; CombineFileInputFormat
中文分詞是中文文本處理的基礎(chǔ), 具有十分重要的理論和應(yīng)用意義[1]。目前中文分詞算法主要有3類:基于詞典的分詞方法,基于概率的分詞方法和基于人工智能的分詞方法。國(guó)內(nèi)一些大的科研機(jī)構(gòu)都對(duì)中文分詞做了研究工作,比如,北京航空航天大學(xué)計(jì)算機(jī)系于設(shè)計(jì)實(shí)現(xiàn)CDWS中文分詞系統(tǒng)[2],中國(guó)科學(xué)院組織開發(fā)了基于多層隱馬爾科夫模型ICTCLAS分詞系統(tǒng)[2]。國(guó)外成熟的中文分詞工具包是IKAnalyzer,它是一個(gè)開源基于JAVA語(yǔ)言的輕量級(jí)的中文分詞第三方工具包[3],采用了特有的“正向迭代最細(xì)粒度切分算法”,支持細(xì)粒度和智能分詞兩種切分模式。IKAnalyzer是以開源項(xiàng)目Lucene[4]為應(yīng)用主體的,結(jié)合詞典分詞和文法分析算法的中文分詞組件。Lucene是Apache基金會(huì)下的一個(gè)非常優(yōu)秀的全文檢索工具軟件包,它可以嵌入在Java系統(tǒng)中,通過(guò)建立倒排鏈表結(jié)構(gòu),建立索引實(shí)現(xiàn)信息檢索,具有高性能、可擴(kuò)展的特點(diǎn)。
但是這些分詞方法都是傳統(tǒng)的串行分詞方法,不足以處理海量數(shù)據(jù),例如微博數(shù)據(jù)[5],它是一種社會(huì)化媒體,包含了豐富的特征信息,具有規(guī)模大、實(shí)時(shí)性強(qiáng)、內(nèi)容口語(yǔ)化、特征屬性多和噪聲大等特征[6]。
由Google實(shí)驗(yàn)室提出的Mapreduce并行分布式計(jì)算模型主要針對(duì)海量數(shù)據(jù)的處理,它能組織集群來(lái)處理大規(guī)模數(shù)據(jù)集,成為云計(jì)算平臺(tái)主流的并行數(shù)據(jù)處理模型[7-8]。本文基于Mapreduce框架,通過(guò)結(jié)合使用IKAnalyzer和Lucene實(shí)現(xiàn)并行分詞。
Mapreduce框架中默認(rèn)使用TextInputFormat文本輸入方式[8],該方式的對(duì)行文本的切分方法不適合處理由大量小文本組成的文件。本文基于CombineFileInputFormat父類,自定義文本輸入方式MyInputFormat,繼承父類getSplits方法,重寫isSplitable方法,并通過(guò)定義MyRecordReader類實(shí)現(xiàn)createRecordReader方法,改進(jìn)文本分片切割方式。實(shí)驗(yàn)證明,基于改進(jìn)后的MyInputFormat文本切片方式比默認(rèn)的TextInputFormat切片方式,更能高效地處理大量文本文件。
1 相關(guān)工作
1.1 MapReduce實(shí)現(xiàn)框架
MapReduce是一種分布式開發(fā)的編程模型[9-10],用戶可以根據(jù)多種語(yǔ)言來(lái)進(jìn)行應(yīng)用程序的編寫。它提供了簡(jiǎn)潔的編程接口,底層框架可以自動(dòng)并行化基于這些接口開發(fā)的程序。由于用戶不需要處理與并行化相關(guān)的工作,可以其中精力編寫業(yè)務(wù)邏輯,開發(fā)效率較高。
MapReduce作為Hadoop的核心計(jì)算模型[11-13],它通過(guò)將輸入數(shù)據(jù)切割為若干個(gè)InputSplit來(lái)實(shí)現(xiàn)并行化。其工作流程如下圖1所示:
1.2 默認(rèn)TextInputFormat輸入方式實(shí)現(xiàn)并行分詞
InputFormat類是MapReduce框架中輸入方式的最頂級(jí)的抽象類,該類從兩個(gè)不同的角度設(shè)定定義了getSplits和createRecordReader兩個(gè)方法。 getSplits方法負(fù)責(zé)切分輸入文件,它把很多的輸入文件切割成很多的輸入分片InputSplit,每個(gè)InputSplit分片都將被交給一個(gè)單獨(dú)的Mapper處理; createRecordReader方法提供了一個(gè)RecordReader對(duì)象,該對(duì)象從InputSplit分片中解析出
FileInputFormat抽象類繼承于InputFormat類,用來(lái)專門處理文件類型的數(shù)據(jù)。該類只實(shí)現(xiàn)了getSplits方法,并沒有實(shí)現(xiàn)createRecordReader方法。getSplits方法返回的分片類型是FileSplit。FileInputFormat在默認(rèn)情況下為文件在HDFS上的每一個(gè)block(128MB)都生成一個(gè)分片,可以通過(guò)設(shè)置作業(yè)的配置參數(shù)mapred.min.split.size和mapred.max.split.size來(lái)設(shè)置分片大小的最小值和最大值,但是一個(gè)分片只能包含來(lái)自于一個(gè)文件的block。
TextInputFormat 類繼承于FileInputFormat類,是MapReduce框架默認(rèn)的文件輸入格式。它繼承了父類getSplits方法。因此,它的分片內(nèi)容只能來(lái)自于一個(gè)文件的block。如果輸入文件有上萬(wàn)個(gè),那么就會(huì)產(chǎn)生上萬(wàn)個(gè)分片,進(jìn)而需要調(diào)用至少上萬(wàn)個(gè)Mapper,這對(duì)于大量小文件而言是工作效率極其低下。該類實(shí)現(xiàn)了createRecordReader方法,該方法返回的是lineRecordReader對(duì)象,該對(duì)象將輸入數(shù)據(jù)每行都解析成一條
每個(gè)分片都只包含來(lái)自于一個(gè)文件的block。每個(gè)split分片都將交由Mapper處理,Mapper端的run方法通過(guò)調(diào)用TextInputFormat方法中返回的lineRecordReader對(duì)象,將分片解析成
2 改進(jìn)數(shù)據(jù)輸入方式實(shí)現(xiàn)并行分詞
TextInputFormat的切分方法默認(rèn)情況下為文件在HDFS上的每一個(gè)block(128MB)都生成一個(gè)分片,并且一個(gè)分片包含的block只能來(lái)自一個(gè)文件。當(dāng)數(shù)據(jù)集由大量的小文件組成時(shí),這種輸入格式是極其低效的。
2.1 自定義MyInputFormat類
首先,自定義繼承于CombineFileInputFormat抽象類的MyInputFormat類。CombineFileInputFormat類繼承于FileInputFormat類,它重載父類的getSplits方法,返回的分片類型是CombineFileSplit。CombineFileSplit類中定義的paths數(shù)組用來(lái)記錄每一個(gè)文件的路徑,即它可包含多個(gè)文件的路徑,這是與TextInputFormat類在分片邏輯上的最大不同之處。MyInputFormat繼承父類的getSplits方法,使得一個(gè)分片可以包含多個(gè)文件的block內(nèi)容。假如file1,file2兩個(gè)文件各有3個(gè)數(shù)據(jù)塊組成,則這兩個(gè)文件的切分結(jié)果示意圖如圖3所示:
其次,MyInputFormat重載父類的isSplitable方法,返回false值來(lái)保證文件不被分割。
第三,MyInputFormat實(shí)現(xiàn)父類createRecordReader方法并返回CombineRecordReader對(duì)象,在該對(duì)象類的構(gòu)造函數(shù)中,定義MyRecordReader來(lái)處理分片內(nèi)的每個(gè)文件。輸出的每條
2.2 自定義MyRecordReader類
CombineFileRecordReader是Hadoop中繼承于RecordReader的可以遍歷包含多個(gè)文件的分片內(nèi)容的框架[9],在其構(gòu)造函數(shù)的中聲明自定義MyRecordReader類來(lái)說(shuō)明將文件解析成
首先,在MyRecordReader類中,定義的變量如表1,重載的方法如表2:
其中,nextKeyValue方法是將文件解析成
2.3 自定義并行分詞MyMapper類
Mapper端的run方法通過(guò)調(diào)用MyInputFormat方法中返回的MyRecordReader對(duì)象,將分片解析成
MapReduce最終實(shí)現(xiàn)文本文件的分詞。文本分詞是特征項(xiàng)提取中最關(guān)鍵的一步,鑒于中英文編碼格式的不同,兩者的分詞格式也不一樣,本文結(jié)合使用IKAnalyzer2012和Lucene實(shí)現(xiàn)分詞。設(shè)置輸出Key為輸入Key,定義StringBuilder對(duì)象存儲(chǔ)分詞結(jié)果,并作為輸出Value.
由于自定義的MyRecordReader的解析邏輯是將文件的類別作為key,文件內(nèi)容作為value,因此分詞過(guò)程只需要經(jīng)過(guò)一個(gè)map方法就可以得到結(jié)果,MapReduce流程圖如下所示:
3 實(shí)驗(yàn)
3.1 實(shí)驗(yàn)環(huán)境
本文實(shí)驗(yàn)環(huán)境:聯(lián)想Z470機(jī)器,Intel Core i3-2410M,2.3 GHz CPU,2GB內(nèi)存,200 GB硬盤,Windows xp 操作系統(tǒng), JAVA編程語(yǔ)言,Eclipse-4.3.2開發(fā)環(huán)境,虛擬機(jī)vmware workstation 10,Centos 6.4,jdk1.6.0_24,Apache Hadoop 1.1.2。在單機(jī)偽分布式環(huán)境下即可證明該實(shí)驗(yàn)的有效性,Hadoop具體環(huán)境如圖7:
3.2 文本數(shù)據(jù)準(zhǔn)備
本文使用的實(shí)驗(yàn)數(shù)據(jù)集是從搜狗實(shí)驗(yàn)室提供的中文文本分類語(yǔ)料庫(kù)(http://www.sogou.com/labs/dl/c.html),該庫(kù)提供有mini版,精簡(jiǎn)版和完整版的文本預(yù)料庫(kù)。在精簡(jiǎn)版中包含共計(jì)9個(gè)類別,每個(gè)類別含1990篇文章,從精簡(jiǎn)版數(shù)據(jù)集中選擇不同數(shù)量的文本組成大小不同的數(shù)據(jù)集,具體數(shù)據(jù)集信息如下表:
3.3 并行分詞
步驟1:分別將在Eclipse上編寫的兩種并行分詞程序打成jar包,使用TextInputFormat方式的jar包命名為TextInputFormat.jar,使用MyInputFormat方式的jar包命名為MyInputFormat.jar,并都存放在/usr/local/目錄下;
步驟2: 在終端執(zhí)行命令”hadoop fs –put /usr/local/sogou /sogou”將數(shù)據(jù)集上傳至hadoop的sogou目錄下;
步驟3: 在終端執(zhí)行命令
”hadoop jar /usr/local/TextInputFormat.jar /usr/local/sogou /sogou /usr/local/sogou /seg1”對(duì)數(shù)據(jù)集按照TextInputFormat方式并行分詞;
步驟4: 在終端執(zhí)行命令
”hadoop jar /usr/local/MyInputFormat.jar /usr/local/sogou /sogou /usr/local/sogou /seg2”對(duì)數(shù)據(jù)集按照MyInputFormat方式并行分詞;
4 結(jié)果對(duì)比與分析
4.1 分詞結(jié)果對(duì)比
在剛開始執(zhí)行時(shí),記錄job總共的Input Paths,并通過(guò)web界面(mlj:50030)查看job的工作狀態(tài),記錄Job運(yùn)行時(shí)間,實(shí)驗(yàn)結(jié)果如下表4:
圖7是兩種輸入方式并行分詞時(shí)間對(duì)比柱狀圖,橫坐標(biāo)表示數(shù)據(jù)集,縱坐標(biāo)表示運(yùn)行時(shí)間,由于兩種方式花費(fèi)時(shí)間相差較大,縱坐標(biāo)采用對(duì)數(shù)坐標(biāo)。由圖7可知,運(yùn)行時(shí)間與數(shù)據(jù)集的大小成正相關(guān),體育和軍事數(shù)據(jù)集花費(fèi)時(shí)間增加相對(duì)較少,說(shuō)明Hadoop更能處理較大的數(shù)據(jù)。
4.2 結(jié)果分析
默認(rèn)輸入方式對(duì)輸入數(shù)據(jù)產(chǎn)生至少與文件個(gè)數(shù)相等的分片,每個(gè)數(shù)據(jù)分片都交給一個(gè)Mapper處理,而且在進(jìn)行過(guò)map之后需要合并到reduce端,這會(huì)大大增加網(wǎng)絡(luò)擁堵。因?yàn)槊總€(gè)Job從建立、 處理、 提交到寫到本地都需要一定的時(shí)間,并且在單機(jī)環(huán)境下只有一個(gè)Mapper, 它只能順序地執(zhí)行每一個(gè)Job。這樣分片的數(shù)目越多,Job需要花費(fèi)的時(shí)間也就越長(zhǎng)。因此處理大量小文件的速度就會(huì)非常慢。
而MyInputFormat文件輸入格式則將所有文件作為一個(gè)分片進(jìn)行處理,輸入方式則允許一個(gè)分片包含多個(gè)文件塊,大大減少了Map個(gè)數(shù),并且改進(jìn)后并不需要reduce合并處理,省去了建立多個(gè)Job所消耗的時(shí)間,這大大提高了并行分詞的效率。
5 結(jié)束語(yǔ)
由于Mapreduce默認(rèn)的TextInputFormat輸入方式非常不適合處理大量小文件組成的數(shù)據(jù)。本文首先基于CombineFileInputFormat父類,自定義文本輸入方式MyInputFormat,繼承父類getSplits方法,重載父類的isSplitable方法保證文件不被分割,并在重載createRecordReader方法時(shí)返回一個(gè)CombineFileRecordReader對(duì)象。第三,自定義MyRecordReader類,指明解析文件的
參考文獻(xiàn):
[1] 韓冬煦, 常寶寶. 中文分詞模型的領(lǐng)域適應(yīng)性方法[J]. 計(jì)算機(jī)學(xué)報(bào), 2015, 38(2).
[2] 曹勇剛, 曹羽中, 金茂忠, 等. 面向信息檢索的自適應(yīng)中文分詞系統(tǒng)[J]. 軟件學(xué)報(bào), 2006, 17(3).
[3] 中文分詞庫(kù) IKAnalyzer[EB/OL].http://www.oschina.net/p/ikanalyzer/.
[4] Apache Lucene [EB/OL].http://lucene.apache.org/.
[5] 張晨逸, 孫建伶, 丁軼群. 基于MB_LDA模型的微博主題挖掘[J]. 計(jì)算機(jī)研究與發(fā)展, 2011, 48(10).
[6] 申國(guó)偉,楊武,王巍,于淼.面向大規(guī)模微博消息流的突發(fā)話題檢測(cè)[J].計(jì)算機(jī)研究與發(fā)展, 2015, 52(2).
[7] 王曉華. MapReduce 2.0源碼分析與編程實(shí)戰(zhàn)[M]. 北京: 人民郵電出版社, 2014.
[8] 應(yīng)毅,劉亞軍. MapReduce 并行計(jì)算技術(shù)發(fā)展綜述[J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2014,23(4).
[9] Eric Sammer.Hadoop技術(shù)詳解[M]. 劉敏, 麥耀鋒, 李冀蕾,等,譯.北京:人民郵電出版社, 2013.
[10] Chuck Lam.Hadoop實(shí)戰(zhàn)[M]. 韓冀中,譯.北京:人民郵電出版社, 2011.
[11] Boris Lublinsky,Smith K T, Alexey Yakubovich. Hadoop高級(jí)編程[M]. 穆玉偉, 靳曉輝,譯. 北京: 清華大學(xué)出版社, 2014.
[12] Owens J R, Jon Lentz, Brian Femiano. Hadoop實(shí)戰(zhàn)手冊(cè)[M]. 傅杰, 趙磊, 盧學(xué)裕,譯. 北京: 人民郵電出版社, 2014.
[13] 張紅蕊, 張永, 于靜雯. 云計(jì)算環(huán)境下基于樸素貝葉斯的數(shù)據(jù)分類[J]. 計(jì)算機(jī)應(yīng)用與軟件, 2015, 32(3).