Hadoop的改進實驗(中文分詞詞頻統計及英文詞頻統計)(1/4)


 

聲明:

 

  1)本文由我bitpeach原創撰寫,轉載時請注明出處,侵權必究。

 

    2)本小實驗工作環境為Windows系統下的百度雲(聯網),和Ubuntu系統的hadoop1-2-1(自己提前配好)。如不清楚配置可看《Hadoop之詞頻統計小實驗初步配置

 

    3)本文由於過長,無法一次性上傳。其相鄰相關的博文,可參見《Hadoop的改進實驗(中文分詞詞頻統計及英文詞頻統計) 博文目錄結構》,以閱覽其余三篇剩余內容文檔。

 

(一)了解百度開放雲

百度開放雲

  • 百度開放雲的內容

    1)開放雲目的

    百度開放研究雲平台由百度開放研究計划支持而建設的。當前已建成基於開源Hadoop 1.0.0而構建的開放數據分析平台,將逐步投入數百台服務器來支持海量數據分析。我們也將不斷在平台上放置來自百度產品和系統的數據供學術研究使用。來自學術界的使用者可以在該平台上開展數據分析的研究。

    網址為:http://openresearch.baidu.com/activity/platform.jspx

    百度開放研究雲平台是面向學術界免費使用的。有意使用者可以向campuscloud@baidu.com發信了解更多信息。為了使用戶在開放研究雲平台上有與通過命令行使用Hadoop一致的體驗,也為了提高在開放環境下使用Hadoop平台的安全性,百度開放研究雲平台提供基於WEB的使用界面,提供類似web shell的使用方式。用戶通過WEB頁面的輸入區域提交命令,並在WEB頁面上展示命令執行過程及相應的輸出信息。

    由於百度開放研究雲平台是面向學術研究的公益性平台,該平台不保證其上數據的可靠性和持久性,請使用者在使用過程注意自己數據的安全,不要泄露隱私和商業秘密。同時,由於該平台還在不斷發展中,缺陷和漏洞在所難免。請使用者隨時告知您的使用意見以讓我們不斷改進。同時,請不要利用平台缺陷和漏洞攻擊該系統或者基於該系統攻擊其它系統。並協調資源利用並合理使用,以便更多的研究者可以在該平台上開展研究工作。。

    2)開放雲項目

    開放雲所開放免費的項目,可如下圖所示。根據下圖可知,開放雲提供Hadoop平台入口,Mahout入口,HBase數據倉庫等,也免費分享一些數據集。

    3)與本門《大數據挖掘》課程的關系

    一是、基於單機配置Hadoop的學習完成之前,可以搶先體驗Hadoop。

    二是、基於單機配置Hadoop的學習完成之后,不滿足於單機分布的雲計算模式,然而又沒有足夠主機實現多分布節點模式的情形下,可以利用百度開放雲。其性能優於單或多個主機,然而不能滿足集群需要。對於有時統計較多數據的情形下,自身筆記本性能不能滿足的情形下,可以嘗試百度雲。

    三是,對於新手而言,或者對於課程入門而言,可以使用百度開放雲,簡化相關操作流程(Mahout或Hadoop插件配置非常復雜且占據主機硬盤),使用百度開放雲可以節約時間,將重點放在多實踐上。

    四是、對於各互聯網公司的雲服務器Hadoop真實集群配置不一定掌握,且配置遠程雲服務器不同於單機,可能出現更多意想不到的問題。有百度開放雲,可以直接利用配置開發好的資源。

百度開放雲的Hadoop平台

  • 百度開放雲Hadoop操作

    我們選擇百度開放雲里的Hadoop入口(使用前隨便注冊一個賬號)

    1)Web Shell命令

    clear(縮寫為cls):清除web Shell的內容。

    logout:退出web shell。

    help:顯示當前可用的命令及簡短說明    

    2)Hadoop命令

    hadoop: 用於訪問Hadoop的功能,其使用方式與命令行使用hadoop的方式一致。對於普通用戶權限,其能夠使用的hadoop命令包括hadoop fs,hadoop jar,hadoop job等。相對於hadoop命令的本地文件系統的當前路徑即為用戶的工作目錄。

    為了訪問hadoop系統的某些模塊,平台也提供了三個變量可以直接使用,包括:    $hadoop_home(hadoop系統的根目錄);

    $hadoop_examples(hadoop-examples-1.0.0.jar的路徑);

    $hadoop_streaming(hadoop-streaming-1.0.0.jar的路徑)。

    3)OS系統指令

    ls: 列舉目錄內容,與Linux命令ls功能和使用方法相同,但所列目錄和文件限於工作目錄內。

    mkdir:創建子目錄,限於工作目錄及其子目錄內。

    mv:移動文件或目錄,移動的文件和目錄必須位於工作目錄下且目標地址也在工作目錄下。

    rm:刪除文件和目錄,所刪除的文件和目錄必須位於工作目錄內。

    upload:從使用者本地通過網頁上載文件到工作目錄下。如圖2所示。運行upload命令后會彈出一個窗口,在該窗口內選擇需要上載的本地文件,點擊"upload"按鈕可以開始上載,而右上角的Status處會顯示上載的進程及結果。當前,上載的目標目錄限定為用戶的工作目錄,還不能選擇其它目標目錄。需要注意的是,上載文件限定為10MB,超過大小限制的文件將無法上載。

    download:從使用者的工作目錄通過網頁下載文件到本地目錄。運行download命令后會彈出窗口讓用戶選擇本地保存的位置。需要注意的是,下載文件的大小限定為10MB,超過大小限制的文件將無法下載。

4)指令使用的注意事項

    一、此百度開放雲的Hadoop系統置於某OS系統內,個人認為是一種服務器式的操作系統。

    二、不支持cd打開文件命令。所以如果想要在文件夾內放文件,必須先新建文件夾,上傳文件與文件夾為平行目錄,然后將平行目錄下的文件mv(剪切)到文件夾內,最后刪掉平行目錄下的文件。這樣就可以完成文件夾內有文件的操作了。很是麻煩。

    三、第一次使用時,你看到Hadoop分布式目錄里會有很多文件,甚至你會看到其他用戶的文件。(當然你進不去其他用戶的目錄,你只是能看見路徑而已,即便如此,隱私性還是不足,因為我看到你的路徑下的文件名后,可以猜測你的工作性質與程序用途。)如下圖所示。這里只展示其他用戶名,沒有給出其他用戶的文件名路徑。

    四、第一次使用時,使用hadoop shell命令查看分布式系統文件,可能會出問題,上面提到可能會看到很多文件,或不應該出現的文件。原因在於,一是你還沒有向分布式系統內傳文件,當你向分布式內傳輸文件后,自然就可以看到。二是百度為共享資源,特別在Hadoop內設置一個共享雲,大家都可以使用。

    五、用過Hadoop知道,分布式目錄大概都在/user/***下,可以是/user/root,也可以是/user/username。在百度開放雲上,建議直接使用簡化變量,即命令如下:

    hadoop fs –ls Input (前提,你已上傳Input目錄文件)

    或者

    hadoop fs –ls /user/username

    但無論如何,不建議使用如下命令

    hadoop fs –ls /user

    原因是前面提到過了,百度開放雲此處還沒有開發完善,這個user里面有大量的私有用戶名字,你雖然看不到文件,也沒有權限打開路徑,但是僅打印名字路徑這一項,就可以使你的電腦卡住,因為賬戶名字實在是太多了(由第三點,就知道我只是截圖截了極少一部分打印出來的賬戶名)。

    六、上傳文件至工作目錄后,再從工作目錄使用hadoop shell命令將文件復制至分布式系統目錄下。

    七、對於文件名過長的問題,指令寫起來比較麻煩,可以使用當前工作目錄下所在文件名使用星號*代替后綴,這個后綴不僅僅是文件類型后綴名,還可以是自動補齊文件名,系統會自動掃描。Web shell不支持Tab補齊,所以星號補齊也是可以考慮的辦法。

(二)基於百度開放雲Hadoop的英文詞頻統計小實驗

百度開放雲Hadoop的詞頻統計

  • 百度開放雲界面下的小實驗

    1)工作目錄上傳文件

    為能夠在Hadoop環境下進行實驗,必須先在系統工作目錄下配置好文件,其幾者之間的關系,我可以認為如下圖所示。通過web shell內的upload指令,將文件上傳至系統工作目錄。

    如果需要對文件目錄進行管理,可以使用OS shell內的mv或rm或mkdir等指令管理。

    2)分布式系統文件配置

    標用Hadoop shell內的fs-put或fs-ls指令,將工作目錄內的文件復制到分布式系統內。本實驗中,主要是兩個txt文本,切記僅僅是兩個txt文本,如果帶入其他可讀文件(例如jar包),否則詞頻統計也會強行讀入,屆時結果可能會是亂碼。如下圖所示,是一開始實驗出現問題的圖片,原因就是我將jar包也放入了txt文本平行目錄,導致也強行讀取了jar包的內容,統計jar包編寫字符的頻率,大多是亂碼。

    3)統計詞頻操作

    由於百度開放雲平台配置好hadoop,則詞頻統計的過程步驟相當輕松。直接利用hadoop shell調用工作目錄下的jar包例程,選擇wordcount程序,並選擇程序要輸入的目錄(在分布式系統內),設置程序輸出所在目錄(也在分布式系統內)。上述描述均有一條指令完成。即

hadoop jar hadoop-examples-1.2.1.jar wordcount Input Output

    當程序執行完畢后,想要查看結果,使用如下指令:

hadoop fs –cat Output/part-r-00000

Hadoop fs –cat Output/*

上述描述的指令過程可由下圖所示。

    4)下載文件

    下載文件時使用Web shell命令download即可。如在分布式系統內,可先由如下指令將分布式文件復制至工作目錄下

    hadoop fs –get Output/part-r-00000 /home/username

    然后再利用百度開放雲的web shell命令中的download指令,如下:

    download /home/username/part-r-00000

    

詞頻統計結果分析

  • 實驗分析

    1)輸出結果正確

    測試文本由兩個,內容分別如下。

hadoop

mahout

hadoop

mahout

python

c

java

jvm

hadoop

hbase

hive

hive

hbase

hadoop

python

python

python

hadoop

hadoop

mahout

mahout

hello world

hello hadoop

hello mahout

hello python

hello c

    輸出結果part-r-00000內容為:

    c     2

hadoop    7

hbase    2

hello    5

hive    2

java    1

jvm     1

mahout    5

python    5

world    1

    2)MapReduce過程分析

   暫缺

改變條件再度測試

  • 實驗分析

    1)三文本,文本區分大小寫

    測試文本由三文本,在上面的文本內容基礎上,第三個文本是為了觀察程序是否區分大小寫(當然,通過閱讀程序也可以,但此項測試為后面的改進鋪墊。)

    下面三圖,分別是MapReduce執行流程,輸入文本內容,輸出統計結果。通過觀察統計結果,發現原程序是區分大小寫的。

----------------------------------------------------------------------------------

---------------------------------------------------------------------------------------

(三)Hadoop的英文詞頻統計改進實驗

英文詞頻統計實驗的改進

  • 改進思路

    1)從工作方式的改進

    工作方式有四個方面的改變:

    一是、利用百度開放雲去測試;

    二是、不再使用hadoop-examples自帶的集成jar包,而是從最基本的java程序開始操作進行打包;

    三是、使用MyEclipse與MapReduce的連接框架進行測試;

    四是、簡單涉獵中文分詞統計詞頻實驗。

    2)從程序上的改進

    編寫java程序,並實施改進。由於水平有限,不能做出太大進步,因而決定,簡單改進兩處。

    一是、向程序內的空格或Tab划分,增加"標點符號"也成為定界符。

    二是、統計單詞忽略大小寫,均轉換成為小寫狀態。

    注意之前利用集成jar包測試時,原程序是區分大小寫的。

    3)改進方案確定為三個方案

    總環境不限,既可以在百度開放雲上,也可以在單機上。(MyEclipse與MapReduce是在單機上的。)

    方案一是、由基本java程序開始,使用文本進行修改編寫,進行基本的打包操作,放在Hadoop上測試。(參看改進實驗方案一步驟)

    方案二是、由基本java程序開始,使用MyEclipse與MapReduce聯合構架,進行軟件與Hadoop的連接測試。(參看第四部分)

    方案三是、簡單涉獵中文分詞背景下的詞頻統計改進實驗。(參看第五部分)

改進實驗方案一步驟

  • 改進實驗步驟

    1)參考編寫WordCount.java程序,並編譯打包

    程序中加粗加卸部分為修改代碼的部分,也即兩個注釋行所在位置。

package org.apache.hadoop.examples;

import java.io.IOException;

import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.io.IntWritable;

import org.apache.hadoop.io.Text;

import org.apache.hadoop.mapreduce.Job;

import org.apache.hadoop.mapreduce.Mapper;

import org.apache.hadoop.mapreduce.Reducer;

import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;

import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import org.apache.hadoop.util.GenericOptionsParser;

public class WordCount {

public static class TokenizerMapper

extends Mapper<Object, Text, Text, IntWritable>{

private final static IntWritable one = new IntWritable(1);

private Text word = new Text();

public void map(Object key, Text value, Context context

) throws IOException, InterruptedException {

StringTokenizer itr = new StringTokenizer(value.toString(),"\t\n\t\f ,.:;?![]()'");

//多定界符,請注意逗號前有一個空格!

while (itr.hasMoreTokens()) {

word.set(itr.nextToken().toLowerCase());//不區分大小寫

context.write(word, one);

}

}

}

public static class IntSumReducer

extends Reducer<Text,IntWritable,Text,IntWritable> {

private IntWritable result = new IntWritable();

public void reduce(Text key, Iterable<IntWritable> values,

Context context

) throws IOException, InterruptedException {

int sum = 0;

for (IntWritable val : values) {

sum += val.get();

}

result.set(sum);

context.write(key, result);

}

}

public static void main(String[] args) throws Exception {

Configuration conf = new Configuration();

String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();

if (otherArgs.length != 2) {

System.err.println("Usage: wordcount <in> <out>");

System.exit(2);

}

Job job = new Job(conf, "word count");

job.setJarByClass(WordCount.class);

job.setMapperClass(TokenizerMapper.class);

job.setCombinerClass(IntSumReducer.class);

job.setReducerClass(IntSumReducer.class);

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(IntWritable.class);

FileInputFormat.addInputPath(job, new Path(otherArgs[0]));

FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));

System.exit(job.waitForCompletion(true) ? 0 : 1);

}

}

 

    2)打成jar包

    我反復強調制作的新程序不同於以往的特點在於兩處:

    a)英文單詞可以使用空格,逗號,感嘆號,問號,括號等分隔,進行統計;

    b)統計時,不區分大小寫,只要是同一個字符內容,都會合並。

    下面展示打成jar包的流程:

    如下圖所示,是展示MyEclipse修改新程序的界面,紅色框內標注出來修改的部分。請注意本截圖較老,也沒有及時更新修正錯誤,本圖里面沒有加入空格定界,即紅框里的上面那個沒有加入空格。如果你需要,尤其是分割新聞時,切記在代碼中加入空格!不要被本圖誤導!具體原因見上面的改進實驗方案一步驟的代碼注釋。

    接下來進行編譯,會發現很多錯誤,那么我們需要鏈接一些庫,鏈接庫的操作,如下圖所示,先選中你的項目,以我為例,我選中左邊資源視圖中的WordCount文件夾,然后右鍵選擇新建鏈接庫路徑。

    然后彈出鏈接庫的文件選擇框,選擇add external jar,如下圖所示:

    點擊開后,我們要選擇需要導入的包,我們打開Hadoop所在的目錄,選擇hadoop目錄內的hadoop/usr/lib里面所有jar包,以及hadoop/hadoop-core-1.2.jar,如下圖所示:

    那么有上述過程,編譯提示的錯誤基本都會消除。然后通過編譯,生成jar包。生成jar包的流程如下圖所示,同樣選擇自己的項目,右鍵選擇Export:

    然后彈出后續界面如下,選擇導出的式jar file,然后基本上點擊next下一步就可以了,請在JAR File Specification對話框內把jar包的生成路徑寫好,點擊next。

    然后是在JAR Packaging Options界面,沒有可填寫的,點擊Next。

    最后是在JAR Manifest Specification界面,一定切記選中主類,否則jar包表面正常打包,但無法調用。選擇Select the class下面的Browse,彈出主類的選擇項,選擇WordCount即可。最終點擊Finish完成所有操作。

    值得一提的是,打成jar包,如果是單獨jar包,需要去掉package這句,且在hadoop內調用時,不再是如下格式:
    $hadoop jar wordcount.jar wordcount Input Output

    而是這樣的格式:
    $hadoop jar wordcount.jar Input Output

    因為hadoop-examples-1.2.1.jar內含有眾多class,其調用格式為

    hadoop jar hadoop-examples-1.2.1.jar [demo jar name] [Input] [Output]

    而我們打好的jar已經是個體戶了,暫時脫離demo集體,故其調用格式為:

    hadoop jar [single jar name] [Input] [Output]

    3)不區分大小寫統計操作

    以如下測試文本:

hi

HI

Hi

hI

HHHHHH

hhhhhh

OOOOOO

PPPPPP

pppppp

oooooo

    使用舊程序(即hadoop-examples1.2.1.jar),統計詞頻是區分大小寫的,其結果如下:

HHHHHH    1

HI    1

Hi    1

OOOOOO    1

PPPPPP    1

hI    1

hhhhhh    1

hi    1

oooooo    1

pppppp    1

    其圖片顯示的結果如下圖所示:

    我們在修改程序得到新程序后,使用百度開放雲hadoop平台,使用新的jar包。操作指令過程可下圖所示(圖片另存放大可看清,親測):

    其結果文字內容如下所示:

hhhhhh    2

hi    4

oooooo    2

pppppp    2

    至於指令內容獲取結果,如下圖所示:

    由上面結果,我們可以看到,新程序確實起了作用。那么我們進入新程序的最后一個綜合階段。

    4)不區分大小寫與多分隔符的統計詞頻操作

    結合質的簡單變化和量的簡單變化,選擇China Daily新聞上的昨日新聞作為測試文本,作為質的變化指單詞分隔符有新內容加入,且不區分大小寫。量的變化指增加樣本。所謂簡單變化意思就是,程序修改不大,改動規模較小甚至極小,樣本量受限於個人時間和精力,而且還要處理相關格式(hadoop還是UTF8比較好),所以在量上,樣本稍多一些,但沒有達到一定數量級。

    以一些新聞樣本的內容簡單示意,注意只是部分內容,完整內容可參看附件。

Cast member Gong Li poses on the red carpet as she arrives for the screening of the film "Coming Home" (Gui lai) out of competition at the 67th Cannes Film Festival in Cannes May 20,2014.Director Zhang Yimou (R) and cast member Zhang Huiwen pose on the red carpet as they arrive for the screening of the film "Coming Home" (Gui lai) out of competition at the 67th Cannes Film Festival in Cannes May 20, 2014.Cast member Gong Li poses on the red carpet as she arrives for the screening of the film "Coming Home" (Gui lai) out of competition at the 67th Cannes Film Festival in Cannes May 20, 2014. Picture taken with a long exposure and lens zoom effect.Cast members Gong Li (L) and Chen Daoming (R) pose on the red carpet as they arrive for the screening of the film "Coming Home" (Gui lai) out of competition at the 67th Cannes Film Festival in Cannes May 20, 2014. Picture taken with a long exposure and lens zoom effect.

    我們將制作好的新程序包上傳至百度開放雲。這里有些注意事項,需要注意。

    Input總是放不進超過兩個以上的文件,事實上是我們沒有了解百度開放雲接口。解決方法是在外部建立文件夾,把你想要分析的文本全部放入。然后使用Hadoop fs –put指令是將外部文件夾的目錄扔進去,百度雲自動會搜索目錄里面的文本,然后Input里面就會出現多個文本了,其指令的流程,可參看下圖。

    我在外部新建了newtest文件夾,把新聞樣本(三個)放進目錄里,然后使用分布式指令,整體扔進Input,然后Input里面就會有多個文本,所以不建議一個一個put進去。然后我們執行jar包,可以得到結果了。hadoop運行的狀態可如下圖所示:

    我們將結果獲取,可觀察內容,文字內容如下所示:

"coming    9

20    9

2014    9

67th    9

a    3

and    7

arrive    5

arrives    3

as    8

at    9

c    1

cannes    18

carpet    8

cast    8

chen    4

competition    9

daoming    4

director    2

during    1

effect    2

exposure    2

festival    9

film    18

for    9

gong    6

gui    9

home"    9

huiwen    4

in    9

l    3

l2    2

lai    9

lens    2

li    6

long    2

marceau    1

may    9

member    4

members    4

of    17

on    8

out    9

photocall    1

picture    2

pose    5

poses    4

r    5

r2    2

red    8

screening    8

she    3

sophie    1

taken    2

the    34

they    5

with    2

yimou    3

zhang    7

zoom    2

actress    1

director    1

    圖片示意的結果,由於單詞行數無法截圖至一張圖內,故截取部分示意。

    如果出現下面問題,如下圖所示說明程序中的分隔符沒有寫入空格,可參看前面所述的代碼注釋,自行調整。

改進實驗方案二和三步驟

  • 改進實驗步驟

    1)方案二步驟(參看第四部分)

    方案二的主要思路是,使用中文文本,然后使用中文分詞程序對其進行詞頻統計,其中我采用傳統的java程序與MapReduce構架。

    2)方案三步驟(參看第五部分)

    方案三的主要思路是,使用英文文本,嘗試使用Python程序和StreamingAPI。我在Python程序上嘗試英文詞頻統計,不使用中文的原因,一是因為python處理中文且運用至hadoop,目前本人水平欠缺,二是中文顯示問題,百度雲不能顯示,單機對於python又極易出錯,故選擇英文文本。

 

 


 <<<<<<<<<  寫在頁面最底的小額打賞  >>>>>>>>>

如果讀者親願意的話,可以小額打賞我,感謝您的打賞。您的打賞是我的動力,非常感激。

必讀:如您願意打賞,打賞方式任選其一,本頁面右側的公告欄有支付寶方式打賞,微信方式打賞。

避免因打賞產生法律問題,兩種打賞方式的任一打賞金額上限均為5元,謝謝您的支持。

如有問題,請24小時內通知本人郵件。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM