分享IKAnalyzer 3.0 中文分詞器

IKAnalyzer3.2.0穩定版已經發布,支持Lucene3.0和solr1.4
鏈接:http://www.javaeye.com/topic/542987

IKAnalyzer V3.1.6GA已發佈,請訪問http://linliangyi2007.javaeye.com/blog/512577

IK Analyzer是一個開源的,基於java語言開發的輕量級的中文分詞工具包。從2006年12月推出1.0版開始, IKAnalyzer已經推出了3個大版本。最初,它是以開源項目Luence爲應用主體的,結合詞典分詞和文法分析算法的中文分詞組件。新版本的IK Analyzer 3.0則發展爲面向Java的公用分詞組件,獨立於Lucene項目,同時提供了對Lucene的默認優化實現。

1.1 IK Analyzer 3.0結構設計


1.2 IK Analyzer 3.0特性

  • 採用了特有的“正向迭代最細粒度切分算法“,具有50萬字/秒的高速處理能力。(IK3.1以上版本已優化至65萬字/秒)
  • 採用了多子處理器分析模式,支持:英文字母(IP地址、Email、URL)、數字(日期,常用中文數量詞,羅馬數字,科學計數法),中文詞彙(姓名、地名處理)等分詞處理。
  • 優化的詞典存儲,更小的內存佔用。支持用戶詞典擴展定義
  • 針對Lucene全文檢索優化的查詢分析器IKQueryParser(作者吐血推薦);採用歧義分析算法優化查詢關鍵字的搜索排列組合,能極大的提高Lucene檢索的命中率。



1.3 分詞效果示例

文本原文1:
IK-Analyzer是一個開源的,基於java語言開發的輕量級的中文分詞工具包。從2006年12月推出1.0版開始, IKAnalyzer已經推出了3個大版本。
分詞結果:
ik-analyzer | 是 | 一個 | 一 | 個 | 開源 | 的 | 基於 | java | 語言 | 開發 |  的 | 輕量級 | 量級 | 的 | 中文 | 分詞 | 工具包 | 工具 |  從  | 2006 | 年 | 12 | 月 | 推出 | 1.0  | 版 | 開始 | ikanalyzer | 已經 |  推出 | 出了 |  3  |  個大 |  個 | 版本

文本原文2:
永和服裝飾品有限公司
分詞結果:
永和 | 和服 | 服裝 | 裝飾品 | 裝飾 | 飾品 | 有限 |  公司

文本原文3:
作者博客:linliangyi2007.javaeye.com   電子郵件:[email protected]
分詞結果:
作者 | 博客 |  linliangyi2007.javaeye.com |  2007 |  電子郵件 |  電子 |  郵件 |  地址 |  [email protected] |  2005

2.使用指南

2.1下載地址
GoogleCode開源項目 :http://code.google.com/p/ik-analyzer/
GoogleCode SVN下載:http://ik-analyzer.googlecode.com/svn/trunk/

2.2安裝部署
IK Analyzer安裝包包含:
1. 《IKAnalyzer中文分詞器V3.0使用手冊》(即本文檔)
2. IKAnalyzer3.0GA.jar
3. IKAnalyzer.cfg.xml
它的安裝部署十分簡單,將IKAnalyzer3.0GA.jar部署於項目的lib目錄中;IKAnalyzer.cfg.xml文件放置在代碼根目錄(對於web項目,通常是WEB-INF/classes目錄,同hibernate、log4j等配置文件相同)下即可。


2.3 Lucene用戶快速入門

代碼樣例

Java代碼 複製代碼
  1. /**  
  2.  * IK Analyzer Demo  
  3.  * @param args  
  4.  */  
  5. import java.io.IOException;   
  6.   
  7. import org.apache.lucene.analysis.Analyzer;   
  8. import org.apache.lucene.document.Document;   
  9. import org.apache.lucene.document.Field;   
  10. import org.apache.lucene.index.CorruptIndexException;   
  11. import org.apache.lucene.index.IndexWriter;   
  12. import org.apache.lucene.search.IndexSearcher;   
  13. import org.apache.lucene.search.Query;   
  14. import org.apache.lucene.search.ScoreDoc;   
  15. import org.apache.lucene.search.TopDocs;   
  16. import org.apache.lucene.store.Directory;   
  17. import org.apache.lucene.store.LockObtainFailedException;   
  18. import org.apache.lucene.store.RAMDirectory;   
  19. //引用IKAnalyzer3.0的類   
  20. import org.wltea.analyzer.lucene.IKAnalyzer;   
  21. import org.wltea.analyzer.lucene.IKQueryParser;   
  22. import org.wltea.analyzer.lucene.IKSimilarity;   
  23.   
  24. /**  
  25.  * @author linly  
  26.  *  
  27.  */  
  28. public class IKAnalyzerDemo {   
  29.        
  30.     public static void main(String[] args){   
  31.         //Lucene Document的域名   
  32.         String fieldName = "text";   
  33.          //檢索內容   
  34.         String text = "IK Analyzer是一個結合詞典分詞和文法分詞的中文分詞開源工具包。它使用了全新的正向迭代最細粒度切分算法。";   
  35.            
  36.         //實例化IKAnalyzer分詞器   
  37.         Analyzer analyzer = new IKAnalyzer();   
  38.         
  39.            
  40.         Directory directory = null;   
  41.         IndexWriter iwriter = null;   
  42.         IndexSearcher isearcher = null;   
  43.         try {   
  44.             //建立內存索引對象   
  45.             directory = new RAMDirectory();     
  46.             iwriter = new IndexWriter(directory, analyzer, true , IndexWriter.MaxFieldLength.LIMITED);   
  47.             Document doc = new Document();   
  48.             doc.add(new Field(fieldName, text, Field.Store.YES, Field.Index.ANALYZED));   
  49.             iwriter.addDocument(doc);   
  50.             iwriter.close();   
  51.                
  52.             //實例化搜索器      
  53.             isearcher = new IndexSearcher(directory);              
  54.             //在索引器中使用IKSimilarity相似度評估器   
  55.             isearcher.setSimilarity(new IKSimilarity());   
  56.                
  57.             String keyword = "中文分詞工具包";   
  58.                
  59.             //使用IKQueryParser查詢分析器構造Query對象   
  60.             Query query = IKQueryParser.parse(fieldName, keyword);   
  61.                
  62.             //搜索相似度最高的5條記錄   
  63.             TopDocs topDocs = isearcher.search(query , 5);   
  64.             System.out.println("命中:" + topDocs.totalHits);   
  65.             //輸出結果   
  66.             ScoreDoc[] scoreDocs = topDocs.scoreDocs;   
  67.             for (int i = 0; i < topDocs.totalHits; i++){   
  68.                 Document targetDoc = isearcher.doc(scoreDocs[i].doc);   
  69.                 System.out.println("內容:" + targetDoc.toString());   
  70.             }              
  71.                
  72.         } catch (CorruptIndexException e) {   
  73.             e.printStackTrace();   
  74.         } catch (LockObtainFailedException e) {   
  75.             e.printStackTrace();   
  76.         } catch (IOException e) {   
  77.             e.printStackTrace();   
  78.         } finally{   
  79.             if(isearcher != null){   
  80.                 try {   
  81.                     isearcher.close();   
  82.                 } catch (IOException e) {   
  83.                     e.printStackTrace();   
  84.                 }   
  85.             }   
  86.             if(directory != null){   
  87.                 try {   
  88.                     directory.close();   
  89.                 } catch (IOException e) {   
  90.                     e.printStackTrace();   
  91.                 }   
  92.             }   
  93.         }   
  94.     }   
  95. }  
/**
 * IK Analyzer Demo
 * @param args
 */
import java.io.IOException;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;
//引用IKAnalyzer3.0的類
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.lucene.IKQueryParser;
import org.wltea.analyzer.lucene.IKSimilarity;

/**
 * @author linly
 *
 */
public class IKAnalyzerDemo {
	
	public static void main(String[] args){
		//Lucene Document的域名
		String fieldName = "text";
		 //檢索內容
		String text = "IK Analyzer是一個結合詞典分詞和文法分詞的中文分詞開源工具包。它使用了全新的正向迭代最細粒度切分算法。";
		
		//實例化IKAnalyzer分詞器
		Analyzer analyzer = new IKAnalyzer();
	 
		
		Directory directory = null;
		IndexWriter iwriter = null;
		IndexSearcher isearcher = null;
		try {
			//建立內存索引對象
			directory = new RAMDirectory();	 
			iwriter = new IndexWriter(directory, analyzer, true , IndexWriter.MaxFieldLength.LIMITED);
			Document doc = new Document();
			doc.add(new Field(fieldName, text, Field.Store.YES, Field.Index.ANALYZED));
			iwriter.addDocument(doc);
			iwriter.close();
			
		    //實例化搜索器   
			isearcher = new IndexSearcher(directory);			
			//在索引器中使用IKSimilarity相似度評估器
			isearcher.setSimilarity(new IKSimilarity());
			
			String keyword = "中文分詞工具包";
			
			//使用IKQueryParser查詢分析器構造Query對象
			Query query = IKQueryParser.parse(fieldName, keyword);
			
			//搜索相似度最高的5條記錄
			TopDocs topDocs = isearcher.search(query , 5);
			System.out.println("命中:" + topDocs.totalHits);
			//輸出結果
			ScoreDoc[] scoreDocs = topDocs.scoreDocs;
			for (int i = 0; i < topDocs.totalHits; i++){
				Document targetDoc = isearcher.doc(scoreDocs[i].doc);
				System.out.println("內容:" + targetDoc.toString());
			}			
			
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (LockObtainFailedException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			if(isearcher != null){
				try {
					isearcher.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(directory != null){
				try {
					directory.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}


執行結果:
命中:1
內容:Document<stored/uncompressed,indexed,tokenized<text:IK Analyzer是一個結合詞典分詞和文法分詞的中文分詞開源工具包。它使用了全新的正向迭代最細粒度切分算法。>>



2.4 關鍵API說明

 類org.wltea.analyzer.lucene.IKAnalyzer
說明:IK分詞器的主類,是IK分詞器的Lucene Analyzer類實現。
該類使用方法請參考 “代碼樣例”章節

 類org.wltea.analyzer.lucene.IKQueryParser
 public static Query parse(String field , String query) throws IOException
說明:單條件,單Field查詢分析
參數1 :String field,  查詢的目標域名稱
參數2 :String query , 查詢的關鍵字
返回值:構造一個單條件,單Field查詢器

 public static Query parseMultiField(String[] fields , String query) throws IOException
說明:多Field,單條件查詢分析
參數1 :String[] fields,  多個查詢的目標域名稱的數組
參數2 :String query , 查詢的關鍵字
返回值:構造一個多Field,單條件的查詢器

 public static Query parseMultiField(String[] fields , String query ,  BooleanClause.Occur[] flags) throws IOException
說明:多Field,單條件,多Occur查詢分析
參數1 :String[] fields,  多個查詢的目標域名稱的數組
參數2 :String query , 查詢的關鍵字
參數3 :BooleanClause.Occur[] flags , 查詢條件的組合方式(Or/And)
返回值:構造一個多Field,單條件,多Occur的查詢器

 public static Query parseMultiField(String[] fields , String[] queries) throws IOException
說明:多Field,多條件查詢分析
參數1 :String[] fields,  多個查詢的目標域名稱的數組
參數2 :String[] queries , 對應多個查詢域的關鍵字數組
返回值:構造一個多Field,多條件的查詢器

 public static Query parseMultiField(String[] fields , String[] queries , BooleanClause.Occur[] flags) throws IOException
說明:多Field,多條件,多Occur查詢
參數1 :String[] fields,  多個查詢的目標域名稱的數組
參數2 :String[] queries , 對應多個查詢域的關鍵字數組
參數3 :BooleanClause.Occur[] flags , 查詢條件的組合方式(Or/And)
返回值:構造一個多Field, 多條件, 多Occur的查詢器

 類org.wltea.analyzer.lucene.IKSimilarity
說明: IKAnalyzer 的相似度評估器。該類重載了DefaultSimilarity的coord方法,提高詞元命中個數在相似度比較中的權重影響,即,當有多個詞元得到匹配時,文檔的相似度將提高。
該類使用方法請參考 “代碼樣例”章節

 類org.wltea.analyzer.IKSegmentation
說明: 這是IK分詞器的核心類。它是真正意義上的分詞器實現。IKAnalyzer的3.0版本有別於之前的版本,它是一個可以獨立於Lucene的Java分詞器實現。當您需要在Lucene以外的環境中單獨使用IK中文分詞 組件時,IKSegmentation正是您要找的。
 public Lexeme next() throws IOException
說明:讀取分詞器切分出的下一個語義單元,如果返回null,表示分詞器已經結束。
返回值:Lexeme 語義單元對象,即相當於Lucene的詞元對象Token

 類org.wltea.analyzer.Lexeme
說明: 這是IK分詞器的語義單元對象,相當於Lucene中的Token詞元對象。由於3.0版本被設計爲獨立於Lucene的Java分詞器實現,因此它需要Lexeme來代表分詞的結果。
 public int getBeginPosition()
說明:獲取語義單元的起始字符在文本中的位置
返回值:int , 語義單元相對於文本的絕對起始位置

 public int getEndPosition()
說明:獲取語義單元的結束字符的下一個位置
返回值:int , 語義單元相對於文本的絕對終止位置的下一個字符位置

 public int getLength()
說明:獲取語義單元包含字符串的長度
返回值:int , 語義單元長度 = getEndPosition – getBeginPosition

 public String getLexemeText()
說明:獲取語義單元包含字符串內容
返回值:String, 語義單元的實際內容,即分詞的結果


3.詞表擴展

目前,IK分詞器自帶的主詞典擁有22萬左右的漢語單詞量。由於作者個人的精力有限,並沒有對蒐集到的詞庫進行全範圍的篩選、清理。此外,對於分詞組件應用場景所涉及的領域的不同,也需要各類專業詞庫的支持。爲此,IK分詞器提供了對詞典的擴充支持。

基於API的詞典擴充
IK分詞器支持使用API編程模型擴充您的詞典。如果您的詞典是存儲與數據庫中,這個方式應該對您適用。API如下:

 類org.wltea.analyzer.dic.Dictionary
說明: IK分詞器的詞典對象。它負責中文詞彙的加載,內存管理和匹配檢索。
 public static void loadExtendWords(List<String> extWords)
說明:加載用戶擴展的詞彙列表到IK的主詞典中,增加分詞器的可識別詞語。
參數1:List<String> extWords , 擴展的詞彙列表
返回值:無

3.2基於配置的詞典擴充
IK分詞器還支持通過配置IKAnalyzer.cfg.xml文件來擴充您的專有詞典。

1. 部署IKAnalyzer.cfg.xml
IKAnalyzer.cfg.xml部署在代碼根目錄下(對於web項目,通常是WEB-INF/classes目錄)同hibernate、log4j等配置文件相同。

2. 詞典文件的編輯與部署
分詞器的詞典文件格式是無BOM的UTF-8編碼的中文文本文件,文件擴展名不限。詞典中,每個中文詞彙獨立佔一行,使用/r/n的DOS方式換行。(注,如果您不瞭解什麼是無BOM的UTF-8格式, 請保證您的詞典使用UTF-8存儲,並在文件的頭部添加一空行)。您可以參考分詞器源碼org.wltea.analyzer.dic包下的.dic文件。

詞典文件應部署在Java的資源路徑下,即ClassLoader能夠加載的路徑中。(推薦同IKAnalyzer.cfg.xml放在一起)


3. IKAnalyzer.cfg.xml文件的配置

Xml代碼 複製代碼
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">     
  3. <properties>     
  4.     <comment>IK Analyzer 擴展配置</comment>  
  5.     <!--用戶可以在這裏配置自己的擴展字典-->  
  6.     <entry key="ext_dict">/mydict.dic ; /mypack/mydict2.dic ; /com/mycompany/dic/mydict3.dic ;</entry>    
  7. </properties>  


在配置文件中,用戶可一次配置多個詞典文件。文件名使用“;”號分隔。文件路徑爲相對java包的起始根路徑。

(全文終)


下載 :IKAnalyzer3.1.1穩定版完整包.rar

更多詳細請參看《IKAnalyzer中文分詞器V3.1.1使用手冊.pdf》

發佈了33 篇原創文章 · 獲贊 1 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章