程式扎記: [ Java 代碼範本 ] mmseg4j : 碼上會！ mmseg4j 中文斷詞java 實作
來源自 這裡 Preface: 照著這篇文章的步驟，你可以使用 mmseg4j 將一串正體(繁體)中文的字串依照詞彙切開，以方便進行中文文字探勘 (Text Mining) 等計算詞頻的工作。mmseg4j 是採用 蔡志浩先生 在2000 年發表的一個中文分詞演算法 ─ MMSeg，它使用兩套演算法與四個模糊解析規則，據稱能達到98.41% 中文斷詞準確率 (理論請參考MMSeg官網)。這樣的準確率已經近似於大陸中科院的 ICTCLAS，973計畫專家組評測第一名的98.5%，此外mmseg4j在斷詞速度表現良好，高達1900kb/s (Simple版本). 此外可喜可賀的是，mmseg4j詞庫採用utf-8編碼 (不像ICTCLAS使用GB) 而且可以自訂，因此只要替換詞庫就可以用來將優美的正體中文進行斷詞，以下來稍微介紹一下詞庫。mmseg4j 預設使用sogou 詞庫 (去除無意義詞)，並合併 rmmseg (Ruby中文斷詞套件) 的詞庫，共14多萬詞。詞庫放在jar裡面，若使用WinRAR等軟體，將下載解開的mmseg4j裡面的mmseg4j-all-X.X.X-with-dic.jar 再解開，裡面的data 資料夾就是詞庫檔預設的位置: * chars.dic：單一字和對應的頻率，提供complex模式使用。* units.dic：單位詞，如：分、秒、年。主要是在數位後面的單位資訊切分好，不與words.dic中的詞有混淆。* words.dic：核心的詞庫檔，一行一詞，不需要其它任何資料，採utf-8編碼。
若要自訂辭典，檔案名必需是 “words” 為首碼和“.dic”為副檔名，例如 wordsXXX.dic。然後我們可以把這個些自訂的詞庫集中在某個資料夾，並在程式中設定讀取這些詞庫檔 (稍後會示範)，也可以把這樣的純文字文件用WinRAR壓縮回mmseg4j-all-X.X.X-with-dic.jar 的data 資料夾中。官網(簡體)下載mmseg4j：mmseg4j 下載mmseg4j 正體(繁體)中文詞庫: 以下詞庫是筆者透過程式工具將原本的詞庫轉為正體字，以方便台港使用者研究學習: * units.dic、words.dic 正體版* mmseg4j-all-1.8.2-with-dic.jar 正體版，我把辭典包在這裡面，所以不介意也可以直接用這個jar (之後 demo 的程式也是使用這個jar)
來吧！我們來斷詞 : 我們要 import 這些東西，如下: view plaincopy to clipboardprint?
import java.io.IOException; import java.io.Reader; import java.io.StringReader; import com.chenlb.mmseg4j.ComplexSeg; import com.chenlb.mmseg4j.Dictionary; import com.chenlb.mmseg4j.MMSeg; import com.chenlb.mmseg4j.Seg; import com.chenlb.mmseg4j.Word; 值得注意的是 import com.chenlb.mmseg4j.ComplexSeg 代表使用 Complex 版本的斷詞 (包含四個模糊規則)；若要使用簡單版本，請換成 import com.chenlb.mmseg4j.SimpleSeg;。接下來，我們在class裡面宣告一個字典型態的變數 dic (儲存詞庫)，並建立建構子與設定一些程式資訊，如下: view plaincopy to clipboardprint?
protected Dictionary dic; public SegChinese() { System.setProperty("mmseg.dic.path", "./src/SegChinese/data"); //這裡可以指定自訂詞庫 dic = Dictionary.getInstance(); } protected Seg getSeg() { return new ComplexSeg(dic); } Seg 方法可以指定要使用的分詞器，在這邊使用 Complex (複雜版的)，並將字典及放入分詞器中。這裡一定要提一下，自訂的字典可以藉由 System.setProperty("mmseg.dic.path", "路徑"); 來指定，其中路徑若是相對路徑的話，是相對於專案資料夾的目錄，在上面的例子中，我故意將字典資料夾放在專案資料夾中的 data/mmseg_dic 路徑下，我們可以在其中放入多個字典檔，就可以使用多個字典. 再來我們要建構程式的斷詞核心部分，如下: view plaincopy to clipboardprint?
public String segWords(String txt, String wordSpilt) throws IOException { Reader input = new StringReader(txt); StringBuilder sb = new StringBuilder(); Seg seg = getSeg(); MMSeg mmSeg = new MMSeg(input, seg); Word word = null; boolean first = true; while((word=mmSeg.next())!=null) { if(!first) { sb.append(wordSpilt); } String w = word.getString(); sb.append(w); first = false; } return sb.toString(); } 這裡我們傳入一個字串與一個希望用來作為分隔的符號，接著使用MMSeg進行分詞，每個詞可以用.next()取得，最後把它變為字串回傳。main 方法以測試程式執行，如下： view plaincopy to clipboardprint?
public static void main(String args[]) throws Exception { SegChinese seg = new SegChinese(); String txt = "這行文字是要被中文斷詞處理的文章，可以從執行結果看斷詞是否成功 莊圓大師"; System.out.println(seg.segWords(txt, " | ")); } Supplement: * CKIP 中文斷詞系統