文分詞 mmseg4j
博客分類: mmseg4j實在想不到其它名字,就稱它爲 mmseg4j。關於 mmseg的算法我先不在這介紹,
可以參考:
mmseg4j 也實現了兩種分詞方式:Simple和Complex。
mmseg4j 擴展 lucene的analyzer,叫MMSegAnalyzer默認使用Complex方式,也可以用SimpleAnalyzer(Simple方式)。
來看下分詞效果。
2009-3-22 22:29:45 com.chenlb.mmseg4j.Dictionary
信息: look up in mmseg.dic.path=../data
2009-3-22 22:29:45 com.chenlb.mmseg4j.Dictionary init
信息: chars loaded time=297ms, line=12638, on file=..\data\chars.dic
2009-3-22 22:29:46 com.chenlb.mmseg4j.Dictionary init
信息: words loaded time=485ms, line=120330, on file=..\data\words.dic
2009-3-22 22:29:46 com.chenlb.mmseg4j.Dictionary init
信息: sort time=125ms
2009-3-22 22:29:46 com.chenlb.mmseg4j.Dictionary init
信息: load dic use time=937ms
羽毛 | 球拍 | 研究 | 生命 | 起源 | 國際化 | 眼看 | 就要 | 來 | 了 | 爲首 | 要 | 考慮 |
mmseg4j還擴展了solr的TokenizerFactory可以在Solr中方便的使用。可以指定詞庫的目錄(paoding 到現在我還沒搞懂怎麼指定詞庫,在solr中使用,只能放到solr.war中)。mmseg4j在solr中使用的示例:
1、把mmseg4j-1.0.jar 放到solr.home/lib目錄下(solr1.3支持)。
2、schema.xml定義field type
- <fieldType name="textComplex" class="solr.TextField" >
- <analyzer>
- <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" dicPath="dic"/>
- </analyzer>
- </fieldType>
- <fieldType name="textSimple" class="solr.TextField" >
- <analyzer>
- <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="simple"
- dicPath="n:/OpenSource/apache-solr-1.3.0/example/solr/my_dic"/>
- </analyzer>
- </fieldType>
3、打開http://localhost:8080/solr/admin/analysis.jsp 察看分詞效果。
MMSegTokenizerFactory 支持兩個參數,mode=simple(默認是complex),dicPath可以用詞庫目錄絕對路徑或相對路徑(相對路徑是是相對solr.home目錄)。可以爲每個不同的MMSegTokenizerFactory指定不同的目錄(一般應用中沒有必要,一般用相同的目錄,默認是CWD的data目錄下找詞庫)。
詞庫,由於mmseg算法的特性要兩個文件,我指定用chars.dic、words.dic,基本上chars.dic不需要改動,words.dic可以添加自己的詞。現在用的是rmmseg的詞庫,當然你也可以用sogou的詞庫(下個版本準備用它)。
現在把 mmseg4j 發在 http://code.google.com/p/mmseg4j/ 上。可以下載 mmseg4j-1.0.jar
發現有 bug,聯繫我 chenlb2008#gmail.com。
http://www.oschina.net/p/mmseg4j
1、mmseg4j 用 Chih-Hao Tsai 的 MMSeg 算法(http://technology.chtsai.org/mmseg/ )實現的中文分詞器,並實現 lucene 的 analyzer 和 solr 的TokenizerFactory 以方便在Lucene和Solr中使用。
2、MMSeg 算法有兩種分詞方法:Simple和Complex,都是基於正向最大匹配。Complex 加了四個規則過慮。官方說:詞語的正確識別率達到了 98.41%。mmseg4j 已經實現了這兩種分詞算法。
- 1.5版的分詞速度simple算法是 1100kb/s左右、complex算法是 700kb/s左右,(測試機:AMD athlon 64 2800+ 1G內存 xp)。
- 1.6版在complex基礎上實現了最多分詞(max-word)。“很好聽” -> "很好|好聽"; “中華人民共和國” -> "中華|華人|共和|國"; “中國人民銀行” -> "中國|人民|銀行"。
- 1.7-beta 版, 目前 complex 1200kb/s左右, simple 1900kb/s左右, 但內存開銷了50M左右. 上幾個版都是在10M左右.
mmseg4j實現的功能詳情請看:
3、在 com.chenlb.mmseg4j.example包裏的類示例了三種分詞效果。
4、 在 com.chenlb.mmseg4j.analysis包裏擴展lucene analyzer。MMSegAnalyzer默認使用max-word方式分詞(還有:ComplexAnalyzer, SimplexAnalyzer, MaxWordAnalyzer)。
5、在 com.chenlb.mmseg4j.solr包裏擴展solr tokenizerFactory。
dicPath 指定詞庫位置(每個MMSegTokenizerFactory可以指定不同的目錄,當是相對目錄時,是相對 solr.home 的目錄),mode 指定分詞模式(simple|complex|max-word,默認是max-word)。
6、運行,詞典用mmseg.dic.path屬性指定或在當前目錄下的data目錄,默認是 ./data 目錄。
java -Dmmseg.dic.path=./data -jar mmseg4j-1.6.jar 這裏是字符串。
java -cp .;mmseg4j-1.6.jar com.chenlb.mmseg4j.example.Simple 這裏是字符串。
java -cp .;mmseg4j-1.6.jar com.chenlb.mmseg4j.example.MaxWord 這裏是字符串
7、一些字符的處理 英文、俄文、希臘、數字(包括①㈠⒈)的分出一連串的。目前版本沒有處理小數字問題, 如ⅠⅡⅢ是單字分,字庫(chars.dic)中沒找到也單字分。
8、詞庫(強制使用 UTF-8):
- data/chars.dic 是單字與語料中的頻率,一般不用改動,1.5版本中已經加到mmseg4j的jar裏了,我們不需要關心它,當然你在詞庫目錄放這個文件可能覆蓋它。
- data/units.dic 是單字的單位,默認讀jar包裏的,你也可以自定義覆蓋它,這功能是試行,如果不喜歡它,可以空的units.dic文件覆蓋它。
- data/words.dic 是詞庫文件,一行一詞,當然你也可以使用自己的,1.5版本使用 sogou 詞庫,1.0的版本是用 rmmseg 帶的詞庫。
- data/wordsxxx.dic 1.6版支持多個詞庫文件,data 目錄(或你定義的目錄)下讀到"words"前綴且".dic"爲後綴的文件。如:data/words-my.dic。
http://www.oschina.net/p/libmmseg/
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平臺,切分速度大約在300K/s(PM-1.2G),截至當前版本(0.7.1)LibMMSeg沒有爲速度仔細優化過,進一步的提升切分速度應仍有空間。
下載
下載 MMSeg 0.7.3
修訂記錄
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.uni的文件,將該文件改名爲uni.lib,完成詞典的構造。需要注意的是,unigram.txt 必須爲UTF-8編碼。
詞典文件格式:
....
河 187
x:187
造假者 1
x:1
臺北隊 1
x:1
湖邊 1
......
其中,每條記錄分兩行。其中,第一行爲詞項,其格式爲:[詞條]\t[詞頻率]。需要注意的是,對於單個字後面跟這個字作單字成詞的頻率,這個頻率 需要在大量的預先切分好的語料庫中進行統計,用戶增加或刪除詞時,一般不需要修改這個數值;對於非單字詞,詞頻率處必須爲1。第二行爲佔位項,是由於 LibMMSeg庫的代碼是從Coreseek其他的分詞算法庫(N-gram模型)中改造而來的,在原來的應用中,第二行爲該詞在各種詞性下的分佈頻 率。LibMMSeg的用戶只需要簡單的在第二行處填"x:1"即可。
用戶可以通過修改詞典文件增加自己的自定義詞,以提高分詞法在某一具體領域的切分精度,系統默認的詞典文件在data/unigram.txt中。
分詞
mmseg -d 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 |
匹配過程終止。最終取“研究”成詞,以相同的方法繼續處理“生命起源”。
分詞效果:
研究_生命_起源_
研究生_教育_