中文分詞實踐(基於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語言實現程式碼
- # 載入rJava、Rwordseg庫
- library(rJava);
- library(Rwordseg);
-
# == 讀入資料
- lecture=read.csv("E:\\worldcup_test.txt",sep=",",header=TRUE,fileEncoding="UTF-8");
- # 檢視前幾行,看是否有字元編碼問題
- head(lecture);
- # 獲取資料集長度
- n=length(lecture[,1]);
- print(n)
- # == 文字預處理
- res=lecture[lecture!=" "];
- #剔除URL
- res=gsub(pattern="http:[a-zA-Z\\/\\.0-9]+","",res);
- #剔除特殊詞
-
res=gsub(pattern="[我|你|的|了|是]","",res);
- # == 分詞+頻數統計
- words=unlist(lapply(X=res, FUN=segmentCN));
- word=lapply(X=words, FUN=strsplit, " ");
- v=table(unlist(word));
- # 降序排序
- v=rev(sort(v));
- d=data.frame(word=names(v), freq=v);
- # 過濾掉1個字和詞頻小於100的記錄
- d=subset(d, nchar(as.character(d$word))>1 & d$freq>=100)
- # == 輸出結果
- 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()新增即可
- # == 新增新詞庫(跑一遍即可)
- installDict("D:\\Program Files\\R\\R-3.1.0\\libword\\myword.txt", dictname="myword")
- installDict("D:\\Program Files\\R\\R-3.1.0\\libword\\foodball.scel", dictname="foodball")
- # 顯示當前手動新增的詞庫
- listDict()
手工新增完詞庫後,分詞效果明顯就上來了:
* 常見問題:文字存在亂碼和特殊字元 => 指令碼過濾
由於帖子屬於UGC內容,一些亂碼和特殊字元會影響R語言處理文字。比如read.cvs()讀入檔案讀到亂碼就返回了,沒能讀入全部文字。
這裡沒有深入去看R語言的字元處理方式,而是選擇繞開這個問題,統一將utf8文字轉成unicode,寫了段Python根據中文的編碼範圍來過濾掉亂碼(替換為" "):
* 常見問題:文字資料量過大 => 切分檔案分批次計算、或使用Hadoop+Smallseg庫
==================================================
* 中文分詞基礎
1、分詞演算法:
a、基於規則(即字串匹配,詞庫組織成字典樹)
- 正向最大匹配:從左到右,"不知道|你|在|說什麼"
- 反向最大匹配:從右到左,"不|知道|你在|說|什麼"
- 最短路徑:切出來的詞最少,"不知道|你在|說什麼"(效果較好)
b、基於詞義(還不成熟)
c、基於統計(概率論)
2、語料庫(詞庫):來源於大量真實文字的加工和訓練
* 中科院ictclas中文分詞系統
中科院的ictclas應該是國內做得最好的中文分詞系統了,例子使用的Rwordseg分詞包就是基於ictclas演算法實現,具體演算法思路可在其官網貼出的相關論文學習到:(http://www.ictclas.org/)