天天看點

Solr 6.0 學習(四)中文IK分詞

IK分詞下載下傳位址:http://git.oschina.net/wltea/IK-Analyzer-2012FF/

IK Analyzer 是一個開源的,基于java語言開發的輕量級的中文分詞工具包。從2006年12月推出1.0版開始, IKAnalyzer已經推出了4個大版本。最初,它是以開源項目Luence為應用主體的,結合詞典分詞和文法分析算法的中文分詞元件。從3.0版本開始,IK發展為面向Java的公用分詞元件,獨立于Lucene項目,同時提供了對Lucene的預設優化實作。在2012版本中,IK實作了簡單的分詞歧義排除算法,标志着IK分詞器從單純的詞典分詞向模拟語義分詞衍化。

IK Analyzer 2012特性:

  1. 采用了特有的“正向疊代最細粒度切分算法“,支援細粒度和智能分詞兩種切分模式;
  2. 在系統環境:Core2 i7 3.4G雙核,4G記憶體,window 7 64位, Sun JDK 1.6_29 64位 普通pc環境測試,IK2012具有160萬字/秒(3000KB/S)的高速處理能力。
  3. 2012版本的智能分詞模式支援簡單的分詞排歧義處理和數量詞合并輸出。
  4. 采用了多子處理器分析模式,支援:英文字母、數字、中文詞彙等分詞處理,相容韓文、日文字元
  5. 優化的詞典存儲,更小的記憶體占用。支援使用者詞典擴充定義。特别的,在2012版本,詞典支援中文,英文,數字混合詞語。

參考:http://www.oschina.net/code/snippet_97202_48660

參考:http://iamyida.iteye.com/blog/2220833?utm_source=tuicool&utm_medium=referral

package com.ng.util.analyzer;
 
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.Tokenizer;
 
public class IKAnalyzer5x extends Analyzer{
 
    private boolean useSmart;
     
    public boolean useSmart() {
        return useSmart;
    }
 
    public void setUseSmart(boolean useSmart) {
        this.useSmart = useSmart;
    }
 
    /**
     * IK分詞器Lucene  Analyzer接口實作類
     * 
     * 預設細粒度切分算法
     */
    public IKAnalyzer5x(){
        this(false);
    }
     
    /**
     * IK分詞器Lucene Analyzer接口實作類
     * 
     * @param useSmart 當為true時,分詞器進行智能切分
     */
    public IKAnalyzer5x(boolean useSmart){
        super();
        this.useSmart = useSmart;
    }
 
     
    /**
    protected TokenStreamComponents createComponents(String fieldName, final Reader in) {
        Tokenizer _IKTokenizer = new IKTokenizer(in , this.useSmart());
        return new TokenStreamComponents(_IKTokenizer);
    }
    **/
     
     
    /**
     * 重寫最新版本的createComponents
     * 重載Analyzer接口,構造分詞元件
     */
    @Override
    protected TokenStreamComponents createComponents(String fieldName) {
        Tokenizer _IKTokenizer = new IKTokenizer5x(this.useSmart());
        return new TokenStreamComponents(_IKTokenizer);
    }
}

package com.ng.util.analyzer;
 
import java.io.IOException;
import java.io.Reader;
 
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.TypeAttribute;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
 
public class IKTokenizer5x extends Tokenizer{
 
     
    //IK分詞器實作
    private IKSegmenter _IKImplement;
     
    //詞元文本屬性
    private final CharTermAttribute termAtt;
    //詞元位移屬性
    private final OffsetAttribute offsetAtt;
    //詞元分類屬性(該屬性分類參考org.wltea.analyzer.core.Lexeme中的分類常量)
    private final TypeAttribute typeAtt;
    //記錄最後一個詞元的結束位置
    private int endPosition;
     
     
    /**
    public IKTokenizer(Reader in , boolean useSmart){
        super(in);
        offsetAtt = addAttribute(OffsetAttribute.class);
        termAtt = addAttribute(CharTermAttribute.class);
        typeAtt = addAttribute(TypeAttribute.class);
        _IKImplement = new IKSegmenter(input , useSmart);
    }**/
     
    /**
     * Lucene 5.x Tokenizer擴充卡類構造函數
     * 實作最新的Tokenizer接口
     * @param useSmart
     */
    public IKTokenizer5x(boolean useSmart){
        super();
        offsetAtt = addAttribute(OffsetAttribute.class);
        termAtt = addAttribute(CharTermAttribute.class);
        typeAtt = addAttribute(TypeAttribute.class);
        _IKImplement = new IKSegmenter(input , useSmart);
    }
 
    /* (non-Javadoc)
     * @see org.apache.lucene.analysis.TokenStream#incrementToken()
     */
    @Override
    public boolean incrementToken() throws IOException {
        //清除所有的詞元屬性
        clearAttributes();
        Lexeme nextLexeme = _IKImplement.next();
        if(nextLexeme != null){
            //将Lexeme轉成Attributes
            //設定詞元文本
            termAtt.append(nextLexeme.getLexemeText());
            //設定詞元長度
            termAtt.setLength(nextLexeme.getLength());
            //設定詞元位移
            offsetAtt.setOffset(nextLexeme.getBeginPosition(), nextLexeme.getEndPosition());
            //記錄分詞的最後位置
            endPosition = nextLexeme.getEndPosition();
            //記錄詞元分類
            typeAtt.setType(nextLexeme.getLexemeTypeString());          
            //返會true告知還有下個詞元
            return true;
        }
        //返會false告知詞元輸出完畢
        return false;
    }
     
    /*
     * (non-Javadoc)
     * @see org.apache.lucene.analysis.Tokenizer#reset(java.io.Reader)
     */
    @Override
    public void reset() throws IOException {
        super.reset();
        _IKImplement.reset(input);
    }   
     
    @Override
    public final void end() {
        // set final offset
        int finalOffset = correctOffset(this.endPosition);
        offsetAtt.setOffset(finalOffset, finalOffset);
    }
}
           

繼續閱讀