1. 程式人生 > >中文分詞實踐(基於R語言)

中文分詞實踐(基於R語言)

    背景:分析使用者在世界盃期間討論最多的話題。

    思路:把使用者關於世界盃的帖子拉下來,然後做中文分詞+詞頻統計,最後將統計結果簡單做個標籤雲,效果如下:

    

    後續:中文分詞是中文資訊處理的基礎,分詞之後,其實還有特別多有趣的文字挖掘工作可以做,也是個知識發現的過程,以後有機會再學習下。

==================================================

* 中文分詞常用實現:

單機:R語言+Rwordseg分詞包 (建議資料量<1G)
分散式:Hadoop+Smallseg庫
詞庫:Sougou詞庫,Sougou輸入法官網可下載
這裡只先介紹單機的實現:
1、R語言:專門用於統計分析、繪圖的語言
2、Rwordseg分詞包:引用了@ansj開發的ansj中文分詞工具,基於中科院的ictclas中文分詞演算法,無論是準確度還是執行效率都超過了rmmseg4j。

* 環境準備 (Windows或Linux版本都行):

R下載:http://mirrors.ustc.edu.cn/CRAN/
Rwordseg包下載:https://r-forge.r-project.org/R/?group_id=1054
rJava包下載:http://cran.r-project.org/web/packages/rJava/index.html
Rwordseg和rJava這些包解壓後放到\R\R-3.1.0\library即可 

* R語言實現程式碼

  1. # 載入rJava、Rwordseg庫  
  2. library(rJava);  
  3. library(Rwordseg);  
  4. # == 讀入資料  
  5. lecture=read.csv("E:\\worldcup_test.txt",sep=",",header=TRUE,fileEncoding="UTF-8");   
  6. # 檢視前幾行,看是否有字元編碼問題  
  7. head(lecture);  
  8. # 獲取資料集長度  
  9. n=length(lecture[,1]);  
  10. print(n)  
  11. # == 文字預處理  
  12. res=lecture[lecture!=" "];  
  13. #剔除URL  
  14. res=gsub(pattern="http:[a-zA-Z\\/\\.0-9]+","",res);   
  15. #剔除特殊詞  
  16. res=gsub(pattern="[我|你|的|了|是]","",res);       
  17. # == 分詞+頻數統計  
  18. words=unlist(lapply(X=res, FUN=segmentCN));  
  19. word=lapply(X=words, FUN=strsplit, " ");  
  20. v=table(unlist(word));    
  21. # 降序排序  
  22. v=rev(sort(v));   
  23. d=data.frame(word=names(v), freq=v);   
  24. # 過濾掉1個字和詞頻小於100的記錄  
  25. d=subset(d, nchar(as.character(d$word))>1 & d$freq>=100)  
  26. # == 輸出結果  
  27. write.csv(d, file="E:\\worldcup_keyword.txt", row.names=FALSE)  

將文字資訊存放在E:\\worldcup_test.txt中,執行後E:\\worldcup_keyword.txt就是儲存了統計完的結果了,截圖如下:word列是詞、freq列是詞頻

* 常見問題:一些詞沒被識別 => 手動新增詞庫

只使用預設詞庫的分詞效果不是很好,最主要問題就是一些球星名字沒有被識別出來,如下圖:

這種情況需要手動新增一些詞庫進來,一般使用Sougou詞庫,在Sougou輸入法的工具箱裡,有細胞詞庫一欄,點選後即可在其官網下載需要的詞庫。

除了使用網上的詞庫,也可以自己手動新增一些詞進去,每個詞一行寫到.txt檔案上,呼叫installDict()新增即可

  1. # == 新增新詞庫(跑一遍即可)   
  2. installDict("D:\\Program Files\\R\\R-3.1.0\\libword\\myword.txt", dictname="myword")  
  3. installDict("D:\\Program Files\\R\\R-3.1.0\\libword\\foodball.scel", dictname="foodball")  
  4. # 顯示當前手動新增的詞庫  
  5. listDict()  

手工新增完詞庫後,分詞效果明顯就上來了:

* 常見問題:文字存在亂碼和特殊字元 => 指令碼過濾

由於帖子屬於UGC內容,一些亂碼和特殊字元會影響R語言處理文字。比如read.cvs()讀入檔案讀到亂碼就返回了,沒能讀入全部文字。

這裡沒有深入去看R語言的字元處理方式,而是選擇繞開這個問題,統一將utf8文字轉成unicode,寫了段Python根據中文的編碼範圍來過濾掉亂碼(替換為" "):

* 常見問題:文字資料量過大 => 切分檔案分批次計算、或使用Hadoop+Smallseg庫

==================================================

* 中文分詞基礎

1、分詞演算法:
    a、基於規則(即字串匹配,詞庫組織成字典樹)
        - 正向最大匹配:從左到右,"不知道|你|在|說什麼"
        - 反向最大匹配:從右到左,"不|知道|你在|說|什麼"
        - 最短路徑:切出來的詞最少,"不知道|你在|說什麼"(效果較好)
    b、基於詞義(還不成熟)
    c、基於統計(概率論)
2、語料庫(詞庫):來源於大量真實文字的加工和訓練

* 中科院ictclas中文分詞系統

中科院的ictclas應該是國內做得最好的中文分詞系統了,例子使用的Rwordseg分詞包就是基於ictclas演算法實現,具體演算法思路可在其官網貼出的相關論文學習到:(http://www.ictclas.org/