LibMMSeg 簡介
LibMMSeg 是Coreseek.com爲 Sphinx 全文搜索引擎設計的中文分詞軟件包,其在GPL協議下發行的中文分詞法,採用Chih-Hao Tsai的MMSEG算法。
MMSEG: A Word Identification System for Mandarin Chinese Text Based on Two Variants of the Maximum Matching Algorithm
Published: 1996-04-29
Updated: 1998-03-06
Document updated: 2000-03-12
License: Free for noncommercial use
Copyright 1996-2006
Chih-Hao Tsai (Email: hao520 at yahoo.com )
您可以在Chih-Hao Tsai's Technology Page找到算法的原文。
LibMMSeg 採用C++開發,同時支持Linux平臺和Windows平臺,切分速度大約在500K/s(酷睿 2.4G);截至目前版本LibMMSeg沒有爲速度做過特殊優化,進一步的提升切分速度仍有空間。
下載
下載 Coreseek-3.2.14+MMSeg 3.2.14,mmseg-3.2.14.tar.gz
mmseg for node.js
MMSeg 的 Node.js 插件,由 zzdhidden 開發。
https://github.com/zzdhidden/mmseg-node
修訂記錄
3.2.14
- 2011.01.12 隨coreseek3.2.14提供
- 修正同義詞庫鎖定問題
3.2.13
- 2010.07.01 隨coreseek3.2.13提供
- 修正chunks問題- 完善多操作系統支持
3.2.12
- 2010.05.03 隨coreseek3.2提供
- 增加了英文和數字的處理部分- 優化了相關處理部分
0.7.3
- 2008.05.27 修正 Makefile 無法安裝csr_typedefs.h的問題
- 2008.05.27 修正 x64系統上編譯無法作爲動態庫的一部分編譯的問題
0.7.2
- 2008.05.19 修正 指定的目錄中無詞典不提示錯誤的問題
- 2008.05.19 新增 Ruby 的調用API
0.7.1
- 2008.04.23 修正了在類似 “english 中文 english" 的句子,切分不正確的問題
0.7
- 第一次發行
安裝
Window平臺
打開源碼包中src\win32 子目錄下的對應的工程文件,目前LibMMSeg內置了VS2003和VS2005的工程文件。
Linux平臺
在源碼包根目錄下執行:
./configure && make && make install
使用
詞典的構造
mmseg -u unigram.txt
該命令執行後,將會在unigram.txt所在目錄中產生一個名爲unigram.txt.uni的文件,將該文件改名爲uni.lib,完成詞典的構造。需要注意的是,unigram.txt需要預先準備,並且編碼格式必須爲UTF-8編碼。
特別提醒:Windows下面編輯詞典文件,請使用Notepad2,絕對不要使用記事本(Notepad)。
詞典文件格式:
....
河 187
x:187
造假者 1
x:1
臺北隊 1
x:1
湖邊 1
......
其中,每條記錄分兩行。其中,第一行爲詞項,其格式爲:[詞條]\t[詞頻率]。特別提醒,有的編輯器會使用4到8個空格代表\t,這將導致該詞條無法解析。需要注意的是,對於單個字後面跟這個字作單字成詞的頻率,這個頻率需要在大量的預先切分好的語料庫中進行統計,用戶增加或刪除詞時,一般不需要修改這個數值;對於非單字詞,詞頻率處必須爲1。第二行爲佔位項,是由於LibMMSeg庫的代碼是從Coreseek其他的分詞算法庫(N-gram模型)中改造而來的,在原來的應用中,第二行爲該詞在各種詞性下的分佈頻率。LibMMSeg的用戶只需要簡單的在第二行處填"x:1"即可。
用戶可以通過修改詞典文件增加自己的自定義詞,以提高分詞法在某一具體領域的切分精度,系統默認的詞典文件在源代碼目錄的data/unigram.txt中。
分詞
mmseg -d <dict_dir> tobe_segment.txt
其中,命令使用‘-d’開關指定詞庫文件所在的位置,參數dict_dir爲詞庫文件(uni.lib )所在的目錄;tobe_segment.txt 爲待切分的文本文件,必須爲UTF-8編碼。如果一切正確,mmseg會將切分結果以及所花費的時間顯示到標準輸出上。
對特殊短語的支持
由於LibMMSeg是爲Sphinx全文搜索引擎設計的,因此其內置了部分搜索引擎切分算法的特性,主要表現在對特殊短語的支持上。
在搜索引擎中,需要處理C++時,如果分詞器中沒有詞組C++,則將被切分爲C/x +/x +/x,在進一步的檢索中,可能每個詞會由於出現的過於頻繁而被過濾掉,導致搜索的結果與C++相關度不高不說,也嚴重影響的全文搜索的速度。在LibMMSeg中,內置對特殊短語的支持。
其輸入文件格式如下
// test commit
.net => dotnet
c# => csharp
c++ => cplusplus
其中左側是待支持的特殊短語,右側是左側的特殊短語需要被轉換爲的短語。這一轉換在分詞前進行。
可以在行的開頭加入'//'作爲註釋符號,發現符號'//'後,整行將被忽略。
特殊短語詞庫構造命令:
mmseg -b exceptions.txt
其中, 開關'-b'指示mmseg是要構造特殊短語詞庫;exceptions.txt是用戶編輯的特殊短語轉換規則。
該命令執行後,將在當前目錄下產生一個名爲"synonyms.dat"的文件,將該文件放在"uni.lib"同一目錄下,分詞系統將自動啓動特殊短語轉換功能。
注意:
1、在啓用了該功能後,如果分詞系統發現了一個特殊短語,將直接輸出其在右側對應的替換的值;
2、右側被替換的值,請保證不會被分詞器進行切分。(eg. C++ => C# 這個轉換的意義不大,並且可能導致C++這個短語永遠無法被檢索到!)
附錄:
MMSeg算法說明
首先來理解一下chunk,它是MMSeg分詞算法中一個關鍵的概念。Chunk中包含依據上下文分出的一組詞和相關的屬性,包括長度(Length)、平均長度(Average Length)、標準差的平方(Variance)和自由語素度(Degree Of Morphemic Freedom)。下面列出了這4個屬性:
屬性 | 含義 |
長度(Length) | chuck中各個詞的長度之和 |
平均長度(Average Length) | 長度(Length)/詞數 |
標準差的平方(Variance) | 同數學中的定義 |
自由語素度(Degree Of Morphemic Freedom) | 各單字詞詞頻的對數之和 |
Chunk中的4個屬性只有在需要該屬性的值時才進行計算,而且只計算一次。
其次來理解一下規則(Rule),它是MMSeg分詞算法中的又一個關鍵的概念。實際上我們可以將規則理解爲一個過濾器(Filter),過濾掉不符合要求的chunk。MMSeg分詞算法中涉及了4個規則:
- 規則1:取最大匹配的chunk (Rule 1: Maximum matching)
- 規則2:取平均詞長最大的chunk (Rule 2: Largest average word length)
- 規則3:取詞長標準差最小的chunk (Rule 3: Smallest variance of word lengths)
- 規則4:取單字詞自由語素度之和最大的chunk (Rule 4: Largest sum of degree of morphemic freedom of one-character words)
這4個規則符合漢語成詞的基本習慣。
再來理解一下匹配方式複雜最大匹配(Complex maximum matching):
複雜最大匹配先使用規則1來過濾chunks,如果過濾後的結果多於或等於2,則使用規則2繼續過濾,否則終止過濾過程。如果使用規則2得到的過濾結果多於或等於2,則使用規則3繼續過濾,否則終止過濾過程。如果使用規則3得到的過濾結果多於或等於2,則使用規則4繼續過濾,否則終止過濾過程。如果使用規則 4得到的過濾結果多於或等於2,則拋出一個表示歧義的異常,否則終止過濾過程。
最後通過一個例句--“研究生命起源"來簡述一下複雜最大匹配的分詞過程。MMSeg分詞算法會得到7個chunk,分別爲:
編號 | chunk | 長度 |
0 | 研_究_生 | 3 |
1 | 研_究_生命 | 4 |
2 | 研究_生_命 | 4 |
3 | 研究_生命_起 | 5 |
4 | 研究_生命_起源 | 6 |
5 | 研究生_命_起 | 5 |
6 | 研究生_命_起源 | 6 |
使用規則1過濾後得到2個chunk,如下:
編號 | chunk | 長度 |
4 | 研究_生命_起源 | 6 |
6 | 研究生_命_起源 | 6 |
計算平均長度後爲:
編號 | chunk | 長度 | 平均長度 |
4 | 研究_生命_起源 | 6 | 2 |
6 | 研究生_命_起源 | 6 | 2 |
使用規則2過濾後得到2個chunk,如下:
編號 | chunk | 長度 | 平均長度 |
4 | 研究_生命_起源 | 6 | 2 |
6 | 研究生_命_起源 | 6 | 2 |
計算標準差的平方後爲:
編號 | chunk | 長度 | 平均長度 | 標準差的平方 |
4 | 研究_生命_起源 | 6 | 2 | 0 |
6 | 研究生_命_起源 | 6 | 2 | 4/9 |
使用規則3過濾後得到1個chunk,如下:
編號 | chunk | 長度 | 平均長度 | 標準差的平方 |
4 | 研究_生命_起源 | 6 | 2 | 0 |
匹配過程終止。最終取“研究”成詞,以相同的方法繼續處理“生命起源”。
分詞效果:
研究_生命_起源_
研究生_教育_
詞彙長度:
默認爲5個UTF-8漢字,如果需要修改,可以如下操作: 1. 打開:mmseg源代碼/css/segmenter.cpp 2. 修改:#define MAX_TOKEN_LENGTH 15 //3*5 3. 重新編譯mmseg和coreseekcoreseek 中文分詞核心配置:
請參考:中文分詞核心配置mmseg.ini配置:(請將其放置到詞典文件uni.lib所在的目錄,並在文件結尾空兩行)
[mmseg] merge_number_and_ascii=0 number_and_ascii_joint= compress_space=1 seperate_number_ascii=0
配置說明:【因爲Sphinx-0.9.9發生變化,導致mmseg.ini的字母和數字切分規則部分無法正常應用,故暫停使用;下一版本將徹底解決該問題】 merge_number_and_ascii : ;合併英文和數字 abc123/x;如果0,則abc123切分爲abc、123;如果1,則abc123爲一個整體;【暫停使用】 number_and_ascii_joint : 定義可以連接英文和數字的字符;該字符將把英文和數字作爲一個整體處理;如果設置爲-,則abc-123將被切分爲abc123;【繼續有效】 compress_space : 預留暫不支持 seperate_number_ascii : 將數字打散;如果0,則123爲一個整體;如果1,則123切分爲1、2、3;【暫停使用】mmseg 同義詞/複合分詞處理:
mmseg 3.2.13版本開始,提供了類似複合分詞的處理方式,供coreseek進行調用。 其基本使用狀況爲: 詞庫包含: 南京西路、南京、西路 索引時: 文本中的“南京西路”會被同時索引爲以上三者 查詢時: 輸入南京西路,可以直接匹配南京西路,而不匹配南京或者西路; 輸入南京或者西路,也可以搜索到南京西路 用法: 1. 處理unigram.txt生成同義詞庫文件 mmseg-3.2.13源代碼/script/build_thesaurus.py unigram.txt > thesaurus.txt thesaurus.txt文件的格式如下:
南京西路 -南京,西路, 張三丰 -太極宗師,武當祖師,2. 生成同義詞詞典 mmseg -t thesaurus.txt3. 將thesaurus.lib放到uni.lib同一目錄4. coreseek索引和搜索時,會自動進行復合分詞處理。如果使用默認的詞庫,沒有做過自定義,則可以直接下載thesaurus.lib,放到uni.lib所在目錄!
使用中如果出現問題,可以查看常見問題解答。