IKAnalyzer分詞器及l(fā)ucene使用IKAnalyzer分析_第1頁
IKAnalyzer分詞器及l(fā)ucene使用IKAnalyzer分析_第2頁
IKAnalyzer分詞器及l(fā)ucene使用IKAnalyzer分析_第3頁
IKAnalyzer分詞器及l(fā)ucene使用IKAnalyzer分析_第4頁
IKAnalyzer分詞器及l(fā)ucene使用IKAnalyzer分析_第5頁
已閱讀5頁,還剩7頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、IKAnalyzer版本Jar包下載IKAnalyzer3.2.8_bin下載地址:下載后包含說明及API文檔(在目錄doc3.2.8中)。源碼下載IKSegmentation淺析(純IK分詞)IKSegmentation是IK中獨(dú)立的分詞器,和lucene沒有關(guān)系。不繼承,不擴(kuò)展,不使用lucene相關(guān)的類。IK主分詞器構(gòu)造函數(shù)/* * IK主分詞器構(gòu)造函數(shù) * param input * param isMaxWordLength 當(dāng)為true時(shí),分詞器進(jìn)行最大詞長切分 */public IKSegmentation(Reader input , boolean isMaxWordLeng

2、th)this.input = input ;segmentBuff = new charBUFF_SIZE;context = new Context(segmentBuff , isMaxWordLength);segmenters = Configuration.loadSegmenter();Reader input 是一個(gè)輸入流,用于讀取文件內(nèi)容。IKSegmentation的構(gòu)造器,作了3個(gè)事1、 new Context(segmentBuff , isMaxWordLength) 創(chuàng)建上下文對(duì)象Contextcontext = new Context(segmentBuff ,

3、isMaxWordLength);Contex主要是存儲(chǔ)分詞結(jié)果集和記錄分詞處理的游標(biāo)位置。2、 Configuration.loadSegmenter() 加載詞典、創(chuàng)建分詞器 Configuration.loadSegmenter() 方法實(shí)現(xiàn)在加載詞典,創(chuàng)建分詞器詳情如下。/* * 初始化子分詞器實(shí)現(xiàn) * (目前暫時(shí)不考慮配置擴(kuò)展) * return List<ISegmenter> */public static List<ISegmenter> loadSegmenter()/初始化詞典單例,如果查看getInstance()發(fā)現(xiàn)里面有詳細(xì)的初始化詞典的相關(guān)方

4、法Dictionary.getInstance();List<ISegmenter> segmenters = new ArrayList<ISegmenter>(4);/處理數(shù)量詞的子分詞器segmenters.add(new QuantifierSegmenter();/處理中文詞的子分詞器segmenters.add(new CJKSegmenter();/處理字母的子分詞器segmenters.add(new LetterSegmenter(); return segmenters;得到Lexeme 這是IK分詞器的語義單元對(duì)象,相當(dāng)于Lucene中的Token

5、詞元對(duì)象。由于3.0版本被設(shè)計(jì)為獨(dú)立于Lucene的Java分詞器實(shí)現(xiàn),因此它需要Lexeme來代表分詞的結(jié)果。調(diào)用的next()方法,會(huì)返回Lexeme 對(duì)象,如果沒有下一個(gè)分詞結(jié)果,會(huì)返回null。源碼如下/* * 獲取下一個(gè)語義單元 * return 沒有更多的詞元,則返回null * throws IOException */public synchronized Lexeme next() throws IOException if(context.getResultSize() = 0)/* * 從reader中讀取數(shù)據(jù),填充buffer * 如果reader是分次讀入buffer

6、的,那么buffer要進(jìn)行移位處理 * 移位處理上次讀入的但未處理的數(shù)據(jù) */int available = fillBuffer(input); if(available <= 0) context.resetContext(); return null; else /分詞處理 int analyzedLength = 0; for(int buffIndex = 0 ; buffIndex < available ; buffIndex+) /移動(dòng)緩沖區(qū)指針 context.setCursor(buffIndex); /進(jìn)行字符規(guī)格化(全角轉(zhuǎn)半角,大寫轉(zhuǎn)小寫處理) segmen

7、tBuffbuffIndex = CharacterHelper.regularize(segmentBuffbuffIndex); /遍歷子分詞器 for(ISegmenter segmenter : segmenters) segmenter.nextLexeme(segmentBuff , context); analyzedLength+; /* * 滿足一下條件時(shí), * 1.available = BUFF_SIZE 表示buffer滿載 * 2.buffIndex < available - 1 && buffIndex > available - BU

8、FF_EXHAUST_CRITICAL表示當(dāng)前指針處于臨界區(qū)內(nèi) * 3.!context.isBufferLocked()表示沒有segmenter在占用buffer * 要中斷當(dāng)前循環(huán)(buffer要進(jìn)行移位,并再讀取數(shù)據(jù)的操作) */ if(available = BUFF_SIZE && buffIndex < available - 1 && buffIndex > available - BUFF_EXHAUST_CRITICAL && !context.isBufferLocked() break; for(ISegmen

9、ter segmenter : segmenters)segmenter.reset(); /System.out.println(available + " : " + buffIndex); /記錄最近一次分析的字符長度 context.setLastAnalyzed(analyzedLength); /同時(shí)累計(jì)已分析的字符長度 context.setBuffOffset(context.getBuffOffset() + analyzedLength); /如果使用最大切分,則過濾交疊的短詞元 if(context.isMaxWordLength() context.

10、excludeOverlap(); /讀取詞元池中的詞元 return buildLexeme(context.firstLexeme(); else/讀取詞元池中的已有詞元return buildLexeme(context.firstLexeme();Lexeme說明n public int getBeginPosition() 說明:獲取詫義單元的起始字符在文本中的位置 返回值:int , 詫義單元相對(duì)于文本的絕對(duì)起始位置 n public int getEndPosition() 說明:獲取詫義單元的結(jié)束字符的下一個(gè)位置 返回值:int , 詫義單元相對(duì)于文本的絕對(duì)終止位置的下一個(gè)字符

11、位置 n public int getLength() 說明:獲取詫義單元包含字符串的長度 返回值:int , 詫義單元長度 = getEndPosition getBeginPosition n public String getLexemeText() 說明:獲取詫義單元包含字符串內(nèi)容 返回值:String, 詫義單元的實(shí)際內(nèi)容,即分詞的結(jié)果 完整代碼示例private static void IKFenCi() FileInputStream fis;try fis = new FileInputStream("F:tmp1234.txt");InputStreamR

12、eader isr=new InputStreamReader(fis, "UTF-8"); BufferedReader br = new BufferedReader(isr); IKSegmentation ik = new IKSegmentation(br, true);Lexeme lex = null;while(lex=ik.next()!=null) System.out.println(lex.getLexemeText()+"| LexemeType ="+lex.getLexemeType() +"| TYPE_CJK_

13、NORMAL= "+lex.TYPE_CJK_NORMAL); catch (FileNotFoundException e) / TODO Auto-generated catch blocke.printStackTrace(); catch (UnsupportedEncodingException e) / TODO Auto-generated catch blocke.printStackTrace(); catch (IOException e) / TODO Auto-generated catch blocke.printStackTrace(); Lucene使用

14、IKAnalyzer分詞實(shí)例化IKAnalyzer分詞器代碼Analyzer analyzer = new IKAnalyzer(true);代碼剖析Analyzer 類是lucene的一個(gè)類org.apache.lucene.analysis.Analyzer,IKAnalyzer類繼承此類(public final class IKAnalyzer extends Analyzer)并覆蓋了tokenStream方法。IKAnalyzer構(gòu)造方法說明它有一個(gè)構(gòu)造方法接收一個(gè)參數(shù)isMaxWordLength,這個(gè)參數(shù)是標(biāo)識(shí)IK是否采用最大詞長分詞,還是采用最細(xì)粒度切分兩種分詞算法。實(shí)際兩種

15、算法的實(shí)現(xiàn),最大詞長切分是對(duì)最細(xì)粒度切分的一種后續(xù)處理,是對(duì)最細(xì)粒度切分結(jié)果的過濾,選擇出最長的分詞結(jié)果。調(diào)用tokenStream()方法返回分詞對(duì)象StringReader reader=new StringReader(“這是要分的詞”); TokenStream ts=analyzer.tokenStream("", reader);追蹤源碼查看真正的分詞對(duì)象1、類IKAnalyzer 的方法 tokenStreampublic TokenStream tokenStream(String fieldName, Reader reader) return new I

16、KTokenizer(reader , isMaxWordLength();返回一個(gè)IKTokenizer對(duì)象2、IKTokenizer類的構(gòu)造器中實(shí)例化了IKSegmentation由此可見IKSegmentation才是真正的分詞實(shí)現(xiàn)。IKSegmentation詳見上面的說明。Lucene如何得到IKSegmentation的分詞結(jié)果1、這里要說到幾個(gè)類org.apache.lucene.analysis.TokenStreamorg.apache.lucene.analysis.Tokenizerorg.wltea.analyzer.lucene.IKTokenizer它們之間的關(guān)系如

17、下圖所示Tokenizer 擴(kuò)展了 TokenStreamIKTokenizer 擴(kuò)展了Tokenizer由上圖可見,IKAnalyzer類的tokenStream()方法返回的是IKTokenizer。2、 再看看IKTokenizer類作了些什么public final class IKTokenizer extends TokenizerIKTokenizer 的構(gòu)造器構(gòu)造器實(shí)例化了IKSegmentation用于分詞。IKTokenizer 擴(kuò)展了Tokenizer覆蓋了其中的幾個(gè)方法方法incrementToken()比較重要,這個(gè)方法用于測試是否還有下一個(gè)分詞結(jié)果,并生成分詞結(jié)果。

18、它會(huì)調(diào)用Lexeme nextLexeme = _IKImplement.next();得到下一個(gè)分詞結(jié)果,如果有,會(huì)存入到屬性(private TermAttribute termAtt;)中,代碼如下:if(nextLexeme != null)/將Lexeme轉(zhuǎn)成Attributes/設(shè)置詞元文本termAtt.setTermBuffer(nextLexeme.getLexemeText();/設(shè)置詞元長度termAtt.setTermLength(nextLexeme.getLength();/設(shè)置詞元位移offsetAtt.setOffset(nextLexeme.getBeginP

19、osition(), nextLexeme.getEndPosition();/記錄分詞的最后位置finalOffset = nextLexeme.getEndPosition();/返會(huì)true告知還有下個(gè)詞元return true;分詞結(jié)果存在termAtt,那么通過什么方法得到呢。通過類org.apache.lucene.analysis.Tokenizer的getAttribute方法得到。代碼如下: TermAttribute term = ts.getAttribute(TermAttribute.class);通過循環(huán)調(diào)用incrementToken()方法可不斷得到分詞結(jié)果,代碼如下: try while(ts.incrementToken() System.out.print(term.toString()+"|&qu

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論