散仙在上篇文章中,介紹過如何使用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類:
java
package com.pigudf; github
import java.io.IOException; 算法
import java.util.List; apache
import org.ansj.domain.Term; 微信
import org.ansj.splitWord.analysis.ToAnalysis; dom
import org.apache.pig.EvalFunc; ide
import org.apache.pig.backend.executionengine.ExecException; svn
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)
本公衆號的內容是有關大數據技術和互聯網等方面內容的分享,也是一個舒適的技術互動交流的小家園,有什麼問題隨時均可以留言,歡迎你們來訪!