1. 程式人生 > >開源 Java 中文分詞器 Ansj 作者孫健專訪

開源 Java 中文分詞器 Ansj 作者孫健專訪

Ansj 是一個開源的 Java 中文分詞工具,基於中科院的 ictclas 中文分詞演算法,比其他常用的開源分詞工具(如mmseg4j)的分詞準確率更高。 

線上演示:http://ansj.sdapp.cn/demo/seg.jsp 
官網地址:http://www.ansj.org/ 
Github地址:https://github.com/ansjsun/ansj_seg 

我們本期採訪了Ansj的作者孫健,請他為大家詳細介紹一下這個分詞工具。 

ITeye期待並致力於為國內優秀的開源專案提供一個免費的推廣平臺,如果你和你的團隊希望將自己的開源專案介紹給更多的開發者,或者你希望我們對哪些開源專案進行專訪,請告訴我們,發站內簡訊給ITeye管理員或者發郵件到[email protected]即可。

先來個自我介紹吧!Top

孫健,胸無大志,沒想過創業,沒想過發財,只想高高興興寫兩行程式碼,做了近五年Java程式設計師,寫過頁面,幹過運維,做過人力,忽悠過客戶,擅長字串操作,擅長資料結構和演算法。現在主要從事檢索、自然語言處理、資料探勘等方面工作。 

介紹一下Ansj!Top

Ansj中文分詞是一款純Java的、主要應用於自然語言處理的、高精度的中文分詞工具,目標是“準確、高效、自由地進行中文分詞”,可用於人名識別、地名識別、組織機構名識別、多級詞性標註、關鍵詞提取、指紋提取等領域,支援行業詞典、使用者自定義詞典。 

上面是客套話,先說明一下Ansj命名的由來吧。本來開始打算叫totoro分詞(同事幫忙起的名),最後發現好多廁所中衛生潔具都叫“TOTO” ^_^ 

正好我註冊了Ansj.org域名,於是乎,就叫這個名字吧。

你認為中文分詞的難點是什麼?Top

在這裡說分詞有點老生常談了。的確,中文分詞已經非常成熟了,但是之間有一些問題依舊比較難解。個人認為大致有以下幾點吧: 

1.  中文歧義的識別
 

比較出名的一句話“結婚的和尚未結婚的”,如果使用正向最大匹配,容易分成“結婚/的/和尚/未/結婚的”,於是有的學者試圖倒過來識別,逆向匹配會大於正向。但是碰到這句“結合成分子時”,採用逆向最大匹配,則會分為“結合/成分/子時”,更有甚者像“咬了獵人的狗”這種語意不明的詞語,就更不容易正確分詞了。這是中文分詞的軟肋。下面是些典型的歧義句: 

  • 交叉歧義(多種切分交織在一起):內塔內亞胡說的/確實/在理
  • 組合歧義(不同情況下切分不同):這個人/手上有痣、我們公司人手
  • 真歧義(幾種切分都可以):乒乓球拍/賣/完了、乒乓球/拍賣/完了
2.  實體名識別 

這個是中文分詞遇到的最大的難點,也是最最緊迫的。實體名識別包括人名識別、地名識別、機構名識別,還包括有監督識別和無監督識別。有監督的還好,無監督基本是無解的,比如“王大力發球”是“王大力”還是“大力發球”,一般人都難以識別。 

3.  新詞熱詞發現
 

目前常用的新詞發現還是一個比較有研究性的課題,雖然有些論文在準確率很高,但是大多是封閉測試,這意味著結果很難應用到實際工程中。目前Ansj採用的新詞發現方式比較簡單,採用了高頻詞的匹配方式,不使用規則,用統計重複串識別新詞,根據詞性去掉干擾詞,雖然有一定的效果,但還是差強人意。 

4.  顆粒度問題 

這個就是一個規則探討的問題了,比如“北京大學”是“北京”+“大學”還是“北京大學”,人各有志,就連同一個人不同時間的標註也有可能是有區別的,雖然這個問題嚴格上來說不屬於技術問題,但是對分詞結果的評測卻有著很大的關係,Ansj採用“能識別就識別”的策略方針,所以在真正R值的時候偏低,總之一句話,適合學術的不一定適合工業,反之亦然。

簡單介紹一下Ansj分詞用到的演算法,其分詞原理是什麼?Top

Ansj並非我創新,可以說是一個ictclas的Java版本,基本原理一致,只不過在分詞優化演算法上做了一些改進。 

該演算法實現分詞有以下幾個步驟: 

  1. 全切分,原子切分;
  2. N最短路徑的粗切分,根據隱馬爾科夫模型和viterbi演算法,達到最優路徑的規劃;
  3. 人名識別;
  4. 系統詞典補充;
  5. 使用者自定義詞典的補充;
  6. 詞性標註(可選)

Ansj分詞的準確率大概是多少?Top

這是我採用人民日報1998年1月語料庫的一個測試結果,首先要說明的是這份人工標註的語料庫本身就有錯誤。 

  • P(準確率):0.984887218571267
  • R(召回率):0.9626488103178712
  • F(綜合指標F值):0.9736410471396494

在歧義、未登入詞問題上,Ansj表現怎樣?Top

歧異方面的處理方式自我感覺還可以,基於“最佳實踐規則+統計”的方式,雖然還有一部分歧異無法識別,但是已經完全能滿足工程應用了。 

至於未登入詞的識別,目前重點做了中文人名的識別,效果還算滿意,識別方式用的“字型+前後監督”的方式,也算是目前我所知道的效果最好的一種識別方式了。

Ansj的效能如何?Top

在我的測試中,Ansj的效率已經遠超ictclas的其他開源實現版本。 

核心詞典利用雙陣列規劃,每秒鐘能達到千萬級別的粗分。在我的MacBookAir上面,分詞速度大約在300w/字/秒,在酷睿i5+4G記憶體組裝機器上,更是達到了400w+/字/秒的速度。

如何新增自定義詞典?Top

Ansj已經實現了使用者自定義詞典的動態新增刪除,當然,也支援從檔案載入詞典。 

從硬碟載入使用者自定義詞典的方法: 

使用者自定義詞典預設路徑:專案目錄/library/userLibrary/userLibrary.dic 

格式為:[自定義詞]  [詞性]  [詞頻],如:csdn創新院  userDefine  1000,中間用TAB鍵隔開 

原分詞結果:[csdn, 創新, 院, 是, 一個, 好, 公司] 

增加詞典後:[csdn創新院, 是, 一個, 好, 公司] 

詳細內容見:使用者自定義詞典的新增 

使用者自定義詞典的動態新增刪除方法見:使用者自定義詞典的動態新增刪除Demo

你在開發過程中,遇到哪些困難?Top

最大的困難是訓練樣本和語料庫的不足,遺憾國內沒有共享,大多數都是收費的,而且好貴。

你認為Ansj還需要在哪些方面進行完善?Top

我打算下一版的改進將圍繞未登入詞進行,採用crf來做新詞的識別。當然隨著系統的龐大,每次修改都要考慮效率記憶體佔用。 

雖然已經著手開始進行中,但是進展一直不快。有興趣的同學可以多提意見,可以通過Github參與到該專案中,讓我們做一個真正的Java版的高準確率分詞。 

Github地址:https://github.com/ansjsun/ansj_seg