中文分詞 (Chinese Word Segmentation) 指的是將一個漢字序列切分成一個一個單獨的詞。分詞就是將連續的字序列按照一定的規範重新組合成詞序列的過程。我們知道,在英文的行文中,單詞之間是以空格作爲自然分界符的,而中文只是字、句和段能通過明顯的分界符來簡單劃界,唯獨詞沒有一個形式上的分界符,雖然英文也同樣存在短語的劃分問題,不過在詞這一層上,中文比之英文要複雜的多、困難的多。下面簡單介紹幾個中文分詞工具。中文版本主要介紹ICTCLAS系列,英文版的包括LingPipe,StarnfordWord Segmenter,以及OpenNlp軟件包。
1. ICTCLAS
1.1. ICTCLAS 介紹
- ICTCLAS (Institute of Computing Technology, Chinese Lexical Analysis System)分詞系統是由中科院計算所的張華平、劉羣所等開發的一套獲得廣泛好評的分詞系統,主要功能包括中文分詞;詞性標註;命名實體識別;新詞識別;同時支持用戶詞典。
- ICTCLAS全部採用C/C++編寫,支持Linux、FreeBSD及Windows系列操作系統,支持C/C++/C#/Delphi/Java等主流的開發語言。
- ICTCLAS採用了層疊隱馬爾可夫模型(Hierarchical Hidden Markov Model),將漢語詞法分析的所有環節都統一到了一個完整的理論框架中,獲得最好的總體效果,相關理論研究發表在頂級國際會議和雜誌上,從理論上和實踐上都證實了該模型的先進性。
1.2. ICTCLAC分詞原理簡介
- 該系統基於隱馬爾科夫模型提出了層疊隱馬爾科夫模型(CHMM),CHMM實際上是若干個層次的簡單HMM組合,各層隱馬爾科夫模型之間以以下幾種方式相互關聯:各層HMM之間共享一個切分詞圖作爲公共數據結構(如圖1),每一層隱馬爾科夫模型都採用N-Best策略,將產生的最好的若干個結果送到此圖中供更高層次的模型使用。
- 該CHMM由低到高依次爲:原子切分,簡單未登錄詞識別,嵌套未登錄詞識別,這幾層中共享二元切分詞圖,並在每層對該數據結構進行修改,使得傳遞給基於類地隱馬分詞的參數越來越準確,最後一層爲隱馬詞性標註。
1.3. ICTCLAC實現版本
1.3.1 原始版本
- ICTCLAS Free版本於 2002 年 8 月 16 日發佈於中文自然語言處理開放平臺(http://www.nlp.org.cn/)並於 2002 年 9 月發佈相應的論文及測試報告。測試報告主要包括國家 973 英漢機器翻譯第二階段的評測報告及在 1998 年 1 月標註人民語料庫上的自評結果。
1.3.2 中科天璣商業版 ICTCLAS漢語分詞系統
- 應用戶要求,作者在原來基礎上做了改進,推出 ICTCLAS 2011。內核版本5.0,改版後分詞速度更快;穩定性更高。 ICTCLAS 2011c/c++/c#版、JNI版均支持多線程調用。以往版本需要進行編碼轉換,統一轉換成GB2312之後才能做進一步處理。系統當前版本支持GB2312、GBK、UTF-8、BIG5等編碼。以上編碼無需做任何轉換,即可進行後續處理。用戶可指定需要處理數據的具體編碼(有利於提高速度)也可讓系統自動識別編碼。本版新增了對繁體中文即BIG5的識別處理。 本版對Windows7支持良好。支持大用戶詞典。
- 該版本的源碼還是C++,不過有java ,C#等的接口
- 下載地址:http://www.ictclas.org/ictclas_download.aspx
測試使用
C++版本沒調試通過,代碼也沒看懂,各種心塞,繼續努力
1.3.3 ICTCLAS4J版本
ICTCLAS4J介紹
ICTCLAS4J中文分詞系統是sinboy在FreeICTCLAS的基礎上完成的一個java開源分詞項目,簡化了原分詞程序的複雜度,旨在爲廣大的中文分詞愛好者一個更好的學習機會。不同於以前的C++版提供的JNI調用,ICTCLAS4J是純Java版本的ICTCLAS。但是也由於開源有很多的不足。
ICTCLAS4J測試使用
- 下載ICTCLAS4J: http://ictclas.org/Down_OpenSrc.asp
- 將下載下的ICTCLAS4J解壓縮得到bin,data,src, segtag.bat 4個文件
- 在Eclipse上建立一個project,命名爲ictclas4jTest
- 把Data文件夾整個拷貝到Eclipse項目的文件夾下,而bin目錄下的org文件夾整個拷貝到Eclipse項目的bin目錄下,把src目錄下的org文件夾整個拷貝到Eclipse項目的src目錄下
- 導入commons-lang.jar http://download.csdn.net/detail/qianwen5201314/7716237
- 現在就可以在你的項目裏新建一個類來試試。這裏新建了一個test類,代碼如下:
- 分詞結果(可以改變源碼使其出現詞性標註)
BUG與不足
- BUG1: 在使用分詞時候,人名會出現漏字問題(如上測試) 。
PosTagger.java文件中人名識別部分personRecognize方法裏面出錯了,註釋掉if (sn.getPos() <4 &&unknownDict.getFreq(sn.getWord(),sn.getPos()) < Utility.LITTLE_FREQUENCY),參見 http://tinypig.iteye.com/blog/250926
- BUG2: AdjustSeg.java裏面的 finaAdjust()函數裏要注意將while語句的判斷條件while (true)改爲while (true && i + 1 < optSegPath.size()) ,否則也可能發生越界錯誤
- BUG3: 當漢字首字節爲負如“癵”*(實際上可能是亂碼),轉換找詞表的時候會發生越界錯誤,這個bug在開源的ictclas裏面也存在,但是c++不檢查越界,因此不報錯。因此在Dictionary.java中的findInOriginalTable方法中加入判斷if(index < 0 || index >=Utility.CC_NUM) return -1;
- 不足:速度比較慢。
代碼裏面用到了很多java的String的操作,這個其實比較廢時間,還有詞典的組織,也是用的String的數組,再二分查找,用hash應該會快一點。
ICTCLAS因爲有一個賣錢的商業版,所以這個開源的版本毛病還是比較多的。比如有一些詞庫中不存在的詞,就會扔空指針的錯誤,比如“深圳”,“大阪”這樣的詞。 還有對一些特殊的字符串模式,比如單引號隔幾個字符再加一個什麼什麼的,就會報錯還有一些特殊的字符,也會報錯。
1.3.4 imdict-Chinese-analyzer版本
imdict-chinese-analyzer簡單介紹
imdict-chinese-analyzer是 imdict智能詞典的智能中文分詞模塊,作者高小平,算法基於隱馬爾科夫模型(Hidden Markov Model, HMM),是中國科學院計算技術研究所的ictclas中文分詞程序的重新實現(基於Java),可以直接爲lucene搜索引擎提供中文分詞支持。
imdict-chinese-analyzer測試使用
- 下載鏈接http://ictclas.org/Down_OpenSrc.asp
- 下到的壓縮包解壓後就是一個java工程,eclipse直接導入即可,但由於其開發的環境是UTF8所以要將eclipse的工作空間的編碼也設置爲utf8,test包裏面的AnalyzerTest就是其用法,看了以後就可以直接用了
imdict-chinese-analyzer優缺點
- 優點
開源,分詞速度快,效率高;
- 缺點
不支持自己添加詞庫,不支持詞性標註(開發人員自己說是爲了提高速度),data文件夾僅自帶了兩個字典coredict核心字典、bigramdict詞關係字典,這是兩個最重要的詞典,沒有地名和人名的詞典,所以要識別人名地名比較麻煩,據說要用層次hmm,先粗分在細分。
1.3.5 ANSJ 版本
ANSJ介紹
- ANSJ 是一個開源的Java 中文分詞工具,基於中科院的 ICTCLAS 中文分詞算法,採用隱馬爾科夫模型(HiddenMarkov Model, HMM)。孫健(ICTCLAS作者張華平的學生)重寫了一個Java版本,並且全部開源,使得 ANSJ可用於人名識別、地名識別、組織機構名識別、多級詞性標註、關鍵詞提取、指紋提取等領域,支持行業詞典、用戶自定義詞典。分詞效果和速度都超過開源版的ICTCLAS.
- ANSJ1.4在原來ANSJ的基礎上做了進一步的改進(類似Stanford word segment)增加了google語義模型+條件隨機場模型的中文分詞的java實現.提供了給予CRF++ wapiti等條件隨即場工具的調用接口.用戶可以及自定義訓練model。目前實現了中文分詞,中文姓名識別 , 用戶自定義詞典,可以應用到自然語言處理等方面。
- 源碼下載:https://github.com/ansjsun/ansj_seg/
- 文檔說明:http://ansjsun.github.io/ansj_seg/
- 作者微博:http://weibo.com/ansjsun
ANSJ測試使用
按照作者的方式使用,但是沒有成功,有待進一步查找原因
1.3.6 Rwordseg版本
Rwordseg簡單介紹
Rwordseg 是一個R環境下的中文分詞工具,使用rJava調用Java分詞工具Ansj。當前版本的Rwordseg包完全引用了 Ansj 包,只是簡單提供了R的接口,並根據R中處理文本的習慣進行了調整,以後可能還會納入其他的分詞工具或者自己開發一些新的功能。
Rwordseg說明
使用說明鏈接 http://jliblog.com/app/rwordseg
安裝與使用
詳細的使用可以參照 R包的中文文檔 Rwordseg_Vignette_CN.pdf
#用於下載安裝rJava 和 Rwordseg,如果安裝了就註釋掉
install.packages("rJava")
install.packages("Rwordseg", repos="http://R-Forge.R-project.org", type="source")
#導入rJava 和Rwordseg
library(rJava)
library(Rwordseg)
#測試rJava 和Rwordseg是否安裝好
teststring1 <- "我愛R語言,我愛文本挖掘"
segmentCN(teststring1)
#觀察分詞1000次花的時間
system.time(for(i in 1:1000) segmentCN(teststring1))
#segmentCN的詳細解釋
?segmentCN
#若輸入參數爲字符向量,則返回列表
segmentCN("結合成分子時")
segmentCN(c("說的的確在理","一次性交多少錢"))
#默認nosymbol爲TURE 不輸出標點,只能有漢字,英文,和數字
segmentCN("我喜歡讀《聖經》,你呢?")
segmentCN("我喜歡讀《聖經》,你呢?",nosymbol=FALSE)
#nature設置 是否輸出詞性 不是很智能 會出現錯誤
segmentCN("花了一元錢買了一朵美麗的花",nature=TRUE)
#參數isNameRecognition 可用來人的名字識別,
getOption("isNameRecognition") #默認是不進行人名識別,輸出false
segmentCN("梅超風不是是桃花島島主")
segment.options(isNameRecognition = TRUE)
getOption("isNameRecognition")
segmentCN("梅超風是桃花島島主")
#對金庸的俠客行進行分詞,分詞的結果會輸出到“俠客行.segment.txt”下
segmentCN("E://Rcode//source//俠客行.txt")
#“俠客行.txt” 364251個字, 大約用時間10S,還是很快的
system.time(segmentCN("E://Rcode//source//俠客行.txt"))
#查看詞典
listDict()
segmentCN("湖北大鼓真是不錯呀")
#導入~.dic詞典,可以直接複製然後改名爲.dic
installDict("E://Rcode//source//default.dic","default")
segmentCN("湖北大鼓真是不錯呀")
#uninstallDict() 刪除安裝的詞典
uninstallDict()
#listDict() 查看剩餘的詞典
listDict()
##用搜狗詞庫的時候 一定要在官網上下載 ~.scel 文件,
#不能直接將 下載的 ~.txt改爲~.scel
segmentCN("牀前明月光,凝視地上霜")
installDict("E://Rcode//source//李白詩集【官方推薦】.scel","libai",dicttype = "scel")
segmentCN("牀前明月光,凝視地上霜")
segmentCN("天罡北斗陣和六脈神劍哪個更厲害")
listDict()
installDict("E://Rcode//source//金庸武功招式.scel","jinyong",dicttype = "scel")
segmentCN("天罡北斗陣和六脈神劍哪個更厲害")
#自定義詞典
#手動添加或刪除詞彙,僅僅只在內存中臨時添加,未記錄下來
segmentCN("畫角聲斷譙門")
insertWords("譙門")
insertWords("畫角")
segmentCN("畫角聲斷譙門")
deleteWords(c("譙門","畫角"))
segmentCN("畫角聲斷譙門")
#使用save參數,把操作記錄下來,下回啓動能直接用
insertWords(c("譙門","畫角"),save=TRUE)
segmentCN("畫角聲斷譙門")
2. LingPipe
2.1. LingPipe簡介
LingPipe是一個自然語言處理的Java開源工具包。LingPipe目前已有很豐富的功能,包括主題分類(Top Classification)、命名實體識別(Named Entity Recognition)、詞性標註(Part-of Speech Tagging)、句題檢測(Sentence Detection)、查詢拼寫檢查(Query Spell Checking)、興趣短語檢測(Interseting Phrase Detection)、聚類(Clustering)、字符語言建模(CharacterLanguage Modeling)、醫學文獻下載/解析/索引(MEDLINEDownload, Parsing and Indexing)、數據庫文本挖掘(DatabaseText Mining)、中文分詞(ChineseWord Segmentation)、情感分析(SentimentAnalysis)、語言辨別(LanguageIdentification)等API。
功能非常強大,最重要的是文檔超級詳細,每個模型甚至連參考論文都列出來了,不僅使用方便,也非常適合模型的學習。
官方地址:http://alias-i.com/lingpipe/
下載地址:http://alias-i.com/lingpipe/web/download.html
2.2. LingPipe中文分詞模塊
UnlikeWestern languages, Chinese is written without spaces between words. Thus to runany word- or token-based linguistic processing on Chinese, it is firstnecessary to determine word boundaries. This tutorial shows how to segmentChinese into words based on LingPipe's spelling corrector.
http://alias-i.com/lingpipe/demos/tutorial/chineseTokens/read-me.html
2.3. Chinese Word Segmentation使用
1.下載最新版本的LingPipe,選擇complete版本
下載地址:http://alias-i.com/lingpipe/web/downloadJarOrDistro.html?
2. 解壓lingpipe-4.1.0.tar
3. 創建LingPipe項目
§ § § § § § |
4. 添加jar包
§ § § § § § |
添加後的eclipse截圖
5.下載測試的Source code,並複製到src下
6.設置訓練參數
mZipFile = new File(args[0],"icwb2-data.zip"); mCorpusName =args[1]; mOutputFile = new File(mCorpusName + ".segments"); mKnownToksFile = new File(mCorpusName + ".knownWords"); mMaxNGram = Integer.valueOf(args[2]); mLambdaFactor = Double.valueOf(args[3]); mNumChars = Integer.valueOf(args[4]); mMaxNBest = Integer.valueOf(args[5]); |
改爲
mZipFile = new File("C://Users//essex.user//Desktop//NLP//icwb2-data.zip"); mCorpusName = "cityu";//根據自己設定 mOutputFile = new File("C://Users//essex.user//Desktop//NLP//cityu.out.segments"); mKnownToksFile = new File(mCorpusName +".knownWords"); mMaxNGram = 5; mLambdaFactor = 5.0; mNumChars = 5000; mMaxNBest = 256; |
下載icwb2-data.zip ,其餘參數按照chinese wordsegmentation 的tutorials設置
Data Directory=e:\data\chineseWordSegBakeoff03
Train Corpus Name=cityu
Test Corpus Name=hk
Output File Name=e:\data\chineseWordSegBakeoff03\cityu.out.segments
Known Tokens File Name=e:\data\chineseWordSegBakeoff03\cityu.out.knownWords
Char Encoding=Big5_HKSCS
Max N-gram=5
Lambda factor=5.0
Num chars=5000
Max n-best=256
Continue weight=0.0
Break weight=0.0
|
3. Stanford Word Segmenter
3.1. Stanford Word Segmenter簡介
Stanford Word Segmenter是斯坦福大學NLP group研發的一套基於CRF的開源中文分詞系統,採用CRF(Conditional Random Fields)算法。速度比ICTCLAS4J快很多,但是不開放字典。
優點:很好處理歧義和未登錄詞問題,效果比基於字符串匹配效果好
缺點:需要大量的人工標註數據,較慢的分詞速度(相比於傳統的字典的最大正向匹配切分)
NLP地址: http://nlp.stanford.edu/
3.2. Stanford Word Segmenter軟件包的使用
1,下載Stanford Word Segmenter軟件包;
Download StanfordWord Segmenter version 2014-06-16
2,在eclipse上建立一個Project StanfordSegmenter。解壓Stanford Word Segmenter軟件包,將其中的data,arabic,test.sipe.utf8文件夾複製到項目下。
3,添加需要的jar包,seg.jar , stanford-segmenter-3.4-javadoc.jar, stanford-segmenter-3.4-sources.jar.
步驟:點擊Project->Properties->JavaBulid Path->Libraries->Add External Jars
4,在項目下,建一個com.Seg包,在包下建立一個SegDemo.java,將解壓出來的SegDemo的內容複製進去。
5,設置運行環境。
運行SegDemo,Run As-> Run Configurations,運行需要傳入參數,test.simp.utf8.
由於Stanford-Sementer佔用的內存比較大,所以需要設置VM arguments,不然就會超內存。
如果機子是64bit的可以設爲,-mx2g。查看解壓出來的segment.sh 文件, 可以看到JAVACMD語句的參數設置。
6,運行結果如下,可以看出分詞的效果。
7,關聯源碼,進一步查看分詞建模的細節。單步運行觀察各個函數的功能。
7.1 對loadClassifierNoExceptions(也可以其他函數)點擊 ctrl+右鍵觀察源碼。結果顯示Source not Found.
7.2 關聯源碼,Attach Source->Extenal File->然後將最開始解壓包中的stanford-segmenter-3.4-sources.jar包加進去。
7.3再次點擊,就可以看得源碼。
8,如果是中文版的eclipse需要改成英文版的。中文版的沒有AttachSource提醒。改變步驟如下:
在eclipse的安裝目錄裏找到eclipse.ini文件,編輯打開,在文件的後面加上 -Duser.language=en這句話,elipse就變成英文版的了
3. OpenNLP
3.1. OpenNLP簡介
OpenNLP是Apache基金會下面的一個機器學習工具包,用於處理自然語言文本。支持大多數常用的 NLP任務,例如:分詞、分句、詞性標註、命名實體識別、主塊分析、句法解析等。其中幾個主要的網址爲:
官網主頁: http://opennlp.apache.org/
用戶手冊: http://opennlp.apache.org/documentation/1.5.3/manual/opennlp.html
模型下載: http://opennlp.sourceforge.net/models-1.5/
OpenNLP不僅提供了訓練好的各種模型,最終要的是,它還允許自己訓練模型.
3.2. OpenNLP使用
3.2.1 使用說明
OpenNLP的使用十分簡單,歸納起來一般都遵循以下幾個步驟:
1. 訓練模型,當然也可以跳過該步驟,而直接使用官方提供的一些已經訓練好的模型;
2. 加載模型,不同任務需要加載不同的模型,通常都是通過構造一個InputStream來加載訓練好的模型;
3. 構造預測器,通過加載進來的訓練好的模型構造預測器;
4. 利用預測器進行NLP相關任務.
3.2.2 測試使用
1. 下載jar包,設置環境
|
2. 使用實例
2.在src上創建Test.java 3.複製下列代碼到test.java中
4.結果"Hi. How are you? This is Mike."被分成兩句。
2.在test類中添加下面的代碼
3.運行結果
2.在test類中添加下面的代碼
3.運行結果
後面幾個部分全部在OpenNlpDemo中測試 code:
|