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