散仙在上篇文章中,介紹過如何使用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)
本公衆號的內容是有關大數據技術和互聯網等方面內容的分享,也是一個溫馨的技術互動交流的小家園,有什麼問題隨時都可以留言,歡迎大家來訪!