如何使用Pig集成分詞器來統計新聞詞頻?
原文 http://qindongliang.iteye.com/blog/2176725
散仙在上篇文章中,介紹過如何使用Pig來進行詞頻統計,整個流程呢,也是非常簡單,只有短短5行代碼搞定,這是由于Pig的內置函數TOKENIZE這個UDF封裝了單詞分割的核心流程,當然,我們的需求是各種各樣的,Pig的內置函數,僅僅解決了80%我們常用的功能,如果稍微我有一些特殊的需求,就會發現內置函數解決不了,不過也無需擔憂,Pig開放了各個UDF的接口和抽象類,從加載,轉換,過濾,存儲等等,都有對應的實現接口,只要我們實現或繼承它,就非常方便擴展。
本篇呢,散仙會使用Ansj分詞器+Pig來統計中文的詞頻,Pig的TOKENIZE只支持對英文句子的切分,為什么呢?因為英文的句子非常工整,都是以空格作為分割符的,而相當于中文來說,則不一樣,中文的切分,需要有詞庫支持,才能分割出一個個詞匯,或者比較暴力一點的,直接根據算法進行 Ngram,也不需要詞庫支持,但這樣切分出來的詞匯,可能大部分時候都不太友好,意義也不太大,目前比較不錯的開源的分詞器有 ansj,ik,meseg4j等,隨便選一款就行,散仙在這里用的ansj的分詞器,有對ansj感興趣的朋友,可以參考 此處
分詞器選好了,分詞功能也實現了,下一步就該考慮如何把這個功能與Pig集成起來,其實答案也很明顯,仿照Pig官方TOKENIZE 源碼 ,再寫一個基于中文分詞功能的UDF,就可以了,對Pig源碼感興趣的朋友可以參考這個 鏈接 ,以Web的形式展示的源碼,非常清晰直觀。
關于如何在Pig中自定義UDF函數,可以參考散仙的這一篇文章:
http://qindongliang.iteye.com/blog/2171303
下面給出,散仙擴展的基于中文分詞的UDF類:
package com.pigudf; import java.io.IOException; import java.util.List; import org.ansj.domain.Term; import org.ansj.splitWord.analysis.ToAnalysis; import org.apache.pig.EvalFunc; import org.apache.pig.backend.executionengine.ExecException; import org.apache.pig.data.BagFactory; import org.apache.pig.data.DataBag; import org.apache.pig.data.DataType; import org.apache.pig.data.Tuple; import org.apache.pig.data.TupleFactory; import org.apache.pig.impl.logicalLayer.schema.Schema; /** * 自定義UDF,實現Pig與中文分詞集成 * **/ public class MyTokenize extends EvalFunc<DataBag> { /**tuple實例**/ TupleFactory mTupleFactory = TupleFactory.getInstance(); /**Bag實例*/ BagFactory mBagFactory = BagFactory.getInstance(); @Override public DataBag exec(Tuple input) throws IOException { try { DataBag output = mBagFactory.newDefaultBag(); Object o = input.get(0); List<Term> terms=ToAnalysis.parse((String)o);//獲取Ansj的分詞 for(Term t:terms){ output.add(mTupleFactory.newTuple(t.getName()));//獲取分詞token,放入tuple,然后以bag的形式組裝tuple } return output; } catch (ExecException ee) { // error handling goes here ee.printStackTrace(); } return null; } /**描述scheaml形式*/ public Schema outputSchema(Schema input) { try{ Schema bagSchema = new Schema(); bagSchema.add(new Schema.FieldSchema("token", DataType.CHARARRAY)); return new Schema(new Schema.FieldSchema(getSchemaName(this.getClass().getName().toLowerCase(), input), bagSchema, DataType.BAG)); }catch (Exception e){ return null; } } }
UDF寫完后,需打成一個jar包,然后在Pig腳本里注冊jar包(依賴的jar包也需要注冊,例如本例中的ansj的jar),關于如何打包,注冊,請參考散仙上篇文章,不要問我上篇文章在哪里,就在這文章里。
最后,我們來看下一個實際例子的效果,,散仙本打算把此篇博客給分析一下,統計下詞頻,看看能不能,通過高頻詞,直接看出本文的主題,后來立馬否決了,因為此刻還沒寫完,不理解的就跳過,最后,從網上找了篇新聞,感興趣的可以閱讀下,原內容如下:
原標題:南水北調辦主任回應境外抹黑:沒什么可藏著掖著 【環球時報綜合報道】1月14日,2015年南水北調工作會議在河南南陽召開,安排部署2015年南水北調工作。在媒體通氣會上,國務院南水北調辦主任鄂竟平對境外一些媒體對南水北調工程的抹黑作出了回應,南水北調辦主要領導就移民補償、國際交流等問題接受了《環球時報》記者的采訪。 環球時報:關于丹江口移民率先的16倍補償,這個標準是如何制定出來的? 國務院南水北調辦征地移民司司長袁松齡:這個16倍的補償措施是我們南水北調工程率先在全國范圍內實行的,在南水北調之前,水利工程的補償基本是8倍到10倍。然而在整個遷區規劃工作來看,8倍10倍標準顯然是太低。我們的規劃也是以人為本,不讓被征遷的移民吃虧,所以按照當時國家標準作參考,南水北調率先實施16倍補償。東、中線移民工程永久征地是96萬畝,臨時用地45萬畝,總體來講,被征遷的群眾對國家的政策是理解和支持的。 環球時報:資料中提到,南水北調移民過程中河南、湖北兩省有18名干部因為過度勞累,犧牲在移民搬遷第一線,可否介紹下具體情況? 國務院南水北調辦征地移民司司長袁松齡:我們34.5萬移民的整體搬遷過程中,有近十萬干部投入到組織工作上。在這十多年以來,先后有18名干部倒在工作崗位上。比如說,湖北有一個叫劉峙清的干部,就是由于工作勞累心臟病突發,倒在了工作崗位上。還有比如河南南陽淅川的干部也是這樣。整個村的移民,在搬遷前的一個晚上,基本都是行李拉起來,車裝好之后,點燃篝火,干部們就陪著,第二天把大家送走。基層的干部基本上每天都和移民們朝夕相處,在搬遷過程中得不到休息,而且很鬧心。我們有很多這樣的事跡。 環球時報:在南水北調工程中,我們是否借鑒過國外的一些經驗,與其他國家的交流情況是怎樣的? 國務院南水北調辦主任鄂竟平:國外的工程,我們考察了幾個,比如美國、德國、加拿大、西班牙等等。總的來說,引水工程中的過程管理有一些可以借鑒,比如說國外有的工程是以公益性地來管理,由政府托管,只按照成本來收取水費,即按照建設和維護這個工程花多少錢來收水費,讓工程自身能良性運行,但不盈利。 咱們國家基本也是按照這個套路來弄的。 再有就是調水的生態問題,也是值得借鑒的,國外在調出區和調入區的生態上,都有一些說法。德國對一些生態方面的規定蠻具體的,比如這條河流,流量到什么數值就要調水了,到什么數字就不能調水了,規定得很具體,管理很精細。這方面咱們應該特別需要注意,尤其是北方一些地區,水資源特別珍貴,如果沒有一個量的概念,就不是很好管。 對于境外一些媒體針對南水北調工程的抹黑,鄂竟平給予了回應,他表示,南水北調工程沒有什么可藏著掖著的,為什么呢?因為它是一個積德的事兒。“北方一些地區的水資源已經緊缺到那樣一個程度了,咱們把寶貴的水資源調來,叫老百姓能喝上好水,讓生態環境不再惡化,大家生活在一個優美的環境里,這不是積德嗎?一個積德的事有什么可藏著掖著的?” 鄂竟平強調,國務院的政策都是透明的,有多少錢、干多少事,達到什么目標都是透明的,媒體什么問題都可以問,都可以討論。“一些境外的媒體,話說的讓人真的不好理解,英國有家媒體,大致意思說‘南水北調是禍國殃民的,引的都是臟水,比如中線,想把水引到東北工業基地,還沒到天津就不能用了’。我們從來就沒有過‘把水引到東北老工業基地’的方案,有些境外媒體說這些話的時候,連事情都搞不清楚,不知道到底是什么居心。” (環球時報記者范凌志)
使用Pig分析完的部分topN結果如下:
(,,77) (的,50) ( ,24) (是,24) (。,23) (南水北調,18) (在,14) (:,12) (工程,12) (移民,11) (有,11) (一些,9) (都,9) (了,9) (到,8) (水,8) ( ,8) (干部,7) (一個,7) (時報,7) (、,7) (工作,7) (中,7) (我們,7) (就,7) (著,7) (什么,7) (環球,7) (媒體,7) (不,6) (來,6) (?,6) (辦,6) (境外,5) (補償,5) (國務院,5) (很,5) (上,5) (過程,4) (引,4) (搬遷,4) (按照,4)
最后來解釋下,在一篇文章里,最多的詞無疑是標點符號,和一些副詞了,這不僅在中文里是這樣,在英文里同樣是這樣的,最多的詞往往是a,the,an,this之類的,副詞什么的,所以統計詞頻前,一般會過濾掉一些無意義的詞,這些散仙就不細說了,相信搞過搜索和自然語言處理的人,都很清楚,從結果前幾個結果來看,確實證明了標點和一些連詞與副詞的頻率最高,終于在結果的第六行,出現了第一個有意義的高頻詞,南水北調,頻率是18次,這直接反映了本文的主題,并與之相關,有意義的高頻詞,一般就是本文的重點介紹內容,這一點在我們的數據挖掘,關鍵詞提取,自然語言處理中用的比較多。
最后總結一下重點:
(1)測試的文本,在使用前是需要傳到HDFS上的。
(2)注冊jar包時,如果有依賴,也需要將依賴jar包注冊在pig里。
(3)在真實的應用中,統計分析前,最好將一些無用的數據給過濾掉。
如果有什么疑問,歡迎掃碼關注微信公眾號:我是攻城師(woshigcs)