15、Analyzer分析器之中文分析器的擴充套件
阿新 • • 發佈:2018-11-01
其實在第五章節裡已經有介紹過下面的分析器了,只是沒有做例子,今天將下面沒有做過例子分析器進行一個例子說明
paoding: 庖丁解牛最新版在
https://code.google.com/p/paoding/
中最多支援Lucene 3.0,且最新提交的程式碼在 2008-06-03,在svn中最新也是2010年提交,已經過時,不予考慮。
mmseg4j:最新版已從
https://code.google.com/p/mmseg4j/
移至
https://github.com/chenlb/mmseg4j-solr
,支援Lucene 4.10,且在github中最新提交程式碼是2014年6月,從09年~14年一共有:18個版本,也就是一年幾乎有3個大小版本,有較大的活躍度,用了mmseg演算法。
IK-analyzer: 最新版在https://code.google.com/p/ik-analyzer/上,支援Lucene 4.10從2006年12月推出1.0版開始, IKAnalyzer已經推出了4個大版本。最初,它是以開源專案Luence為應用主體的,結合詞典分詞和文法分析演算法的中文分片語件。從3.0版本開 始,IK發展為面向Java的公用分片語件,獨立於Lucene專案,同時提供了對Lucene的預設優化實現。在2012版本中,IK實現了簡單的分詞 歧義排除演算法,標誌著IK分詞器從單純的詞典分詞向模擬語義分詞衍化。 但是也就是2012年12月後沒有在更新。 這裡我們不在說明這個分析器,感興趣的小夥伴可以看看第5章節的說明哦
ansj_seg:最新版本在
https://github.com/NLPchina/ansj_seg
tags僅有1.1版本,從2012年到2014年更新了大小6次,但是作者本人在2014年10月10日說明:“可能我以後沒有精力來維護ansj_seg了”,現在由”nlp_china”管理。2014年11月有更新。並未說明是否支援Lucene,是一個由CRF(條件隨機場)演算法所做的分詞演算法。
imdict-chinese-analyzer:最新版在
https://code.google.com/p/imdict-chinese-analyzer/
, 最新更新也在2009年5月,下載原始碼,不支援Lucene 4.10 。是利用HMM(隱馬爾科夫鏈)演算法。
Jcseg:最新版本在git.oschina.net/lionsoul/jcseg,支援Lucene 4.10,作者有較高的活躍度。利用mmseg演算法。
MMseg 的分析器的使用 首先將引用相關的jar包,
主要參考的文件 http://codepub.cn/2016/03/23/Maven-project-integrating-Lucene-Chinese-Segmentation-tools-Jcseg-and-Ansj/
MMseg 的分析器的使用 首先將引用相關的jar包,
<!--mmseg4j 的分析器的使用 -->
<dependency>
<groupId>com.chenlb.mmseg4j</groupId>
<artifactId>mmseg4j-core</artifactId>
<version>1.10.0</version>
</dependency>
具體程式碼的實現
package mmseg;
import com.chenlb.mmseg4j.*;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
/**
* Created by kangz on 2016/12/19.
*/
public class MMsegAnalyzerTest {
public static void main(String[] args) throws IOException {
String txt = "";
txt = "那個好看的笑容裡面全是悲傷白富美,他在行屍走肉的活著,他的故事悲傷的像一場沒有結局的黑白電影,他是她小說裡的主角, 她懂他,他愛過她,她不知道自己是愛他的的外表,還是愛他的故事,還是愛他身上的那個自己。";
File file = new File("D:\\LucentTest\\luceneIndex2");//詞典的目錄
Dictionary dic = Dictionary.getInstance();//建立詞典例項,與比較老的版本中不相同。不能直接new。 預設讀取的是jar包中 words.dic(可修改其內容)也可指定詞典目錄 可以是 File 也可以是String 的形式
Seg seg = null;
//seg = new SimpleSeg(dic);//簡單的
seg = new ComplexSeg(dic);//複雜的
MMSeg mmSeg = new MMSeg(new StringReader(txt), seg);
Word word = null;
while((word = mmSeg.next())!=null) {
if(word != null) {
System.out.print(word + "|");
}
}
}
}
Jcseg 的分析器的使用
首先將引用相關的jar包,
<!--Jcseg 的分析器的使用 -->
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>jcseg-core</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>jcseg-analyzer</artifactId>
<version>2.0.1</version>
</dependency>
Lucene整合Jcseg的測試程式碼
將jcseg原始碼包中的
lexicon和
jcseg.properties兩個檔案複製到src/main/resources下,並修改
jcseg.properties中的lexicon.path = src/main/resources/lexicon
新建一個類:
package lexicon;
import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import org.lionsoul.jcseg.analyzer.v5x.JcsegAnalyzer5X;
import org.lionsoul.jcseg.tokenizer.core.JcsegTaskConfig;
import java.io.File;
import java.nio.file.Paths;
/**
* Created by kangz on 2016/12/19.
*/
public class LexiconAnalyzersTest {
@Test
public void test() throws Exception {
//如果不知道選擇哪個Directory的子類,那麼推薦使用FSDirectory.open()方法來開啟目錄 建立一個分析器物件
Analyzer analyzer = new JcsegAnalyzer5X(JcsegTaskConfig.COMPLEX_MODE);
//非必須(用於修改預設配置): 獲取分詞任務配置例項
JcsegAnalyzer5X jcseg = (JcsegAnalyzer5X) analyzer;
JcsegTaskConfig config = jcseg.getTaskConfig();
//追加同義詞, 需要在 jcseg.properties中配置jcseg.loadsyn=1
config.setAppendCJKSyn(true);
//追加拼音, 需要在jcseg.properties中配置jcseg.loadpinyin=1
config.setAppendCJKPinyin(true);
//更多配置, 請檢視 org.lionsoul.jcseg.tokenizer.core.JcsegTaskConfig
/** ------------------------------------------------------------------------ **/
// 開啟索引庫
// 指定索引庫存放的位置
Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
//建立一個IndexwriterConfig物件
//第一個引數:lucene的版本,第二個引數:分析器物件
IndexWriterConfig indexWriterConfig=new IndexWriterConfig(analyzer);
//建立一個Indexwriter物件
IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);
indexWriter.deleteAll();//清除之前的索引 注: 全部刪除索引, 請慎用。
//讀取檔案資訊
//原始文件存放的目錄
File path = new File("D:\\LucentTest\\luceneFile");
for (File file:path.listFiles()) {
if (file.isDirectory()) continue;
//讀取檔案資訊
//檔名
String fileName = file.getName();
//檔案內容
String fileContent = FileUtils.readFileToString(file);
//檔案的路徑
String filePath = file.getPath();
//檔案的大小
long fileSize = FileUtils.sizeOf(file);
//建立文件物件
Document document = new Document();
//建立域
//三個引數:1、域的名稱2、域的值3、是否儲存 Store.YES:儲存 Store.NO:不儲存
Field nameField = new TextField("name", fileName, Field.Store.YES);
Field contentField = new TextField("content", fileContent, Field.Store.YES);
Field sizeField=new LongPoint("size",fileSize);
Field pathField = new StoredField("path", filePath);
//把域新增到document物件中
document.add(nameField);
document.add(contentField);
document.add(pathField);
document.add(sizeField);
//把document寫入索引庫
indexWriter.addDocument(document);
}
indexWriter.close();
}
//使用查詢
@Test
public void testTermQuery() throws Exception {
//以讀的方式開啟索引庫
Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex"));
//建立一個IndexReader
IndexReader indexReader = DirectoryReader.open(directory);
//建立一個IndexSearcher物件
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//建立一個查詢物件
Query query = new TermQuery(new Term("content", "全文檢索"));
//執行查詢
TopDocs topDocs = indexSearcher.search(query,10);
System.out.println("查詢結果總數量:" + topDocs.totalHits);
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
//取document物件
Document document = indexSearcher.doc(scoreDoc.doc);
System.out.println("得分:" + scoreDoc.score);
//System.out.println(document.get("content"));
System.out.println(document.get("path"));
}
indexReader.close();
}
}
ansj分析器的使用
首先要引用jar包
Maven專案配置Ansj
根據官方手冊,在
pom.xml
檔案中加入依賴,如下所示
<!--ansj 的分析器的使用-->
<dependency>
<groupId>org.ansj</groupId>
<artifactId>ansj_seg</artifactId>
<version>5.0.2</version>
</dependency>
<dependency>
<groupId>org.ansj</groupId>
<artifactId>ansj_lucene5_plug</artifactId>
<version>5.0.3.0</version>
</dependency>
Lucene整合Ansj的測試程式碼
Ansj In Lucene
的官方參考文件:
http://nlpchina.github.io/ansj_seg/
到
https://github.com/NLPchina/ansj_seg
下載
ZIP
壓縮檔案,解壓,將其中的
library
資料夾和
library.properties
檔案拷貝到
maven
專案下的
src/main/resources
中,修改
library.properties
內容如下
#redress dic file path
ambiguityLibrary=src/main/resources/library/ambiguity.dic
#path of userLibrary this is default library
userLibrary=src/main/resources/library/default.dic
#path of crfModel
crfModel=src/main/resources/library/crf.model
#set real name
isRealName=true
具體的程式碼如下
package ansj;
import org.ansj.library.UserDefineLibrary;
import org.ansj.lucene5.AnsjAnalyzer;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.nio.file.Paths;
import java.util.Date;
/**
* Created by kangz on 2016/12/19.
*/
public class AnsjAnalyzerTest {
/**
* 簡單測試 AnsjAnalyzer的效能及基礎應用
* @throws IOException
*/
@Test
public void test() throws IOException {
Analyzer ca = new AnsjAnalyzer(AnsjAnalyzer.TYPE.index);
Reader sentence = new StringReader(
"全文檢索是將整本書java、整篇文章中的任意內容資訊查找出來的檢索,java。它可以根據需要獲得全文中有關章、節、段、句、詞等資訊,計算機程式通過掃描文章中的每一個詞");
TokenStream ts = ca.tokenStream("sentence", sentence);
System.out.println("start: " + (new Date()));
long before = System.currentTimeMillis();
while (ts.incrementToken()) {
System.out.println(ts.getAttribute(CharTermAttribute.class));
}
ts.close();
long now = System.currentTimeMillis();
System.out.println("time: " + (now - before) / 1000.0 + " s");
}
@Test
public void indexTest() throws IOException, ParseException {
Analyzer analyzer = new AnsjAnalyzer(AnsjAnalyzer.TYPE.index);
Directory directory = FSDirectory.open(Paths.get("D:\\LucentTest\\luceneIndex2"));
IndexWriter iwriter;
UserDefineLibrary.insertWord("蛇藥片", "n", 1000);
// 建立一個IndexWriterConfig 物件
IndexWriterConfig config = new IndexWriterConfig(analyzer);// 建立indexwriter物件
IndexWriter indexWriter = new IndexWriter(directory, config);
// 建立一個文件物件
Document document = new Document();
Field nameField = new TextField("text", "季德勝蛇藥片 10片*6板 ", Field.Store.YES);
nameField.boost();
document.add(nameField);
//寫入索引庫
indexWriter.addDocument(document);
indexWriter.commit();
indexWriter.close();
System.out.println("索引建立完畢");
search(analyzer, directory, "\"季德勝蛇藥片\"");
}
//封裝索引查詢
private void search(Analyzer queryAnalyzer, Directory directory, String queryStr) throws IOException, ParseException {
IndexSearcher isearcher;
DirectoryReader directoryReader = DirectoryReader.open(directory);
// 查詢索引
isearcher = new IndexSearcher(directoryReader);
QueryParser tq = new QueryParser("text", queryAnalyzer);
Query query = tq.parse(queryStr);
System.out.println(query);
TopDocs hits = isearcher.search(query, 5);
System.out.println(queryStr + ":共找到" + hits.totalHits + "條記錄!");
for (int i = 0; i < hits.scoreDocs.length; i++) {
int docId = hits.scoreDocs[i].doc;
Document document = isearcher.doc(docId);
System.out.println(toHighlighter(queryAnalyzer, query, document));
}
}
//
private String toHighlighter(Analyzer analyzer, Query query, Document doc) {
String field = "text";
try {
SimpleHTMLFormatter simpleHtmlFormatter = new SimpleHTMLFormatter("<font color=\"red\">", "</font>");
Highlighter highlighter = new Highlighter(simpleHtmlFormatter, new QueryScorer(query));
TokenStream tokenStream1 = analyzer.tokenStream("text", new StringReader(doc.get(field)));
String highlighterStr = highlighter.getBestFragment(tokenStream1, doc.get(field));
return highlighterStr == null ? doc.get(field) : highlighterStr;
} catch (IOException | InvalidTokenOffsetsException e) {
}
return null;
}
}
主要參考的文件 http://codepub.cn/2016/03/23/Maven-project-integrating-Lucene-Chinese-Segmentation-tools-Jcseg-and-Ansj/
下面是小編的微信轉帳二維碼,小編再次謝謝讀者的支援,小編會更努力的
----請看下方↓↓↓↓↓↓↓
百度搜索 Drools從入門到精通:可下載開源全套Drools教程
深度Drools教程不段更新中:
更多Drools實戰陸續釋出中………
掃描下方二維碼關注公眾號 ↓↓↓↓↓↓↓↓↓↓