je分詞用lucene.中文分詞庖丁解牛
一般使用
使用評估
參考資料
下載
開始使用
分詞策略
效果體驗
在命令行模式下執行analyzer.bat(windows)或analyzer.sh(linux)即可0
u 顯示幫助
E:\Paoding-Analysis>analyzer.bat ?
u 分詞對話
多次輸入或粘貼不同的文字內容,查看分詞效果,如:
E:\Paoding-Analysis>analyzer.bat
paoding> |
此時使用者可以在光標所在所在位置(|)輸入或粘貼待分詞的內容(以分號結束),按下Enter鍵換行,analyzer.bat便可以輸出分詞結果。
paoding> 中文分詞;
1: 中文/分詞/
分詞器net.paoding.analysis.analyzer.PaodingAnalyzer
內容長度 4字符, 分 2個詞
分詞耗時 0ms
--------------------------------------------------
分詞完畢後,又會進入以上對話模式。
鍵入:e或:q退出會話 (包括:符號) 。
鍵入:?顯示幫助(包括:符號) 。
u 對文件進行分詞
analyzer.bat允許對指定的文件進行分詞體驗。文件以路徑名給出可以使絕對地址、相對當前目錄的地址,或以classpath:爲前綴的類路徑地址。示例如下:
paoding> :-f E:/content.txt
paoding> :-f E:/content.txt -c gbk
paoding> :-f E:/content.txt -c gbk -m max
開始使用
第一步:安裝詞典
將程序存儲在某個目錄下,這個目錄稱爲安裝目錄!
將程序拷貝到安裝目錄稱爲安裝程序!
增加、刪除、修改程序稱爲自定製程序!
第二步:配置詞典系統環境變量
庖丁中文分詞需要一套詞典,使用者安裝辭典後,應該設置系統環境變量PAODING_DIC_HOME指向詞典安裝目錄。
在windows下,通過“我的電腦”屬性之“高級”選項卡,然後在進入“環境變量”編輯區,新建環境變量,設置“變量名”爲PAODING_DIC_HOME;“變量值”爲E:/data/paoding/dic
工程中使用分詞,dic文件包copy到 web-info/classes 下面!
第三步:將庖丁JAR類庫導入工程
將paoding-analysis.jar添加到工程。
至此,便可以在應用代碼中使用庖丁提供的中文分析器了。
提醒:以下示例代碼中的IDNEX_PATH表示索引庫地址,讀者運行以下代碼前,應該賦與一個不重要的地址,比如/data/paoding/test_index 或E:/paoding_test_index,以免一時疏忽將重要數據丟失。
- package net.paoding.analysis;
- import net.paoding.analysis.analyzer.PaodingAnalyzer;
- import org.apache.lucene.analysis.Analyzer;
- import org.apache.lucene.analysis.TokenStream;
- import org.apache.lucene.document.Document;
- import org.apache.lucene.document.Field;
- import org.apache.lucene.index.IndexReader;
- import org.apache.lucene.index.IndexWriter;
- import org.apache.lucene.index.TermPositionVector;
- import org.apache.lucene.queryParser.QueryParser;
- import org.apache.lucene.search.Hits;
- import org.apache.lucene.search.IndexSearcher;
- import org.apache.lucene.search.Query;
- import org.apache.lucene.search.Searcher;
- import org.apache.lucene.search.highlight.Formatter;
- import org.apache.lucene.search.highlight.Highlighter;
- import org.apache.lucene.search.highlight.QueryScorer;
- import org.apache.lucene.search.highlight.TokenGroup;
- import org.apache.lucene.search.highlight.TokenSources;
- /**
- * 創建索引庫
- * @author Administrator
- *
- */
- public class CreateIndexLibTest {
- public static void main(String[] args) throws Exception {
- /** 創建分詞 */
- // 詞典目錄
- String path = "D:\\Java\\paoding_analyzer\\dic";
- // 庖丁解牛中文分詞器
- Analyzer analyzer = new PaodingAnalyzer();
- // 索引書寫器
- IndexWriter writer = new IndexWriter(path, analyzer, true);
- // 文檔
- Document doc = new Document();
- // 字段
- Field field = new Field(
- "content", // name
- "你好,世界!", // value
- Field.Store.YES, // store
- Field.Index.TOKENIZED, // index
- Field.TermVector.WITH_POSITIONS_OFFSETS); // termVector
- doc.add(field); // 文檔添加字段
- writer.addDocument(doc); // 索引書寫器添加文檔
- writer.close();
- System.out.println("Indexed success!");
- /** 搜索關鍵詞 */
- // 索引讀取器
- IndexReader reader = IndexReader.open(path);
- // 查詢解析器
- QueryParser parser = new QueryParser("content", analyzer);
- Query query = parser.parse("你好"); // 解析
- // 搜索器
- Searcher searcher = new IndexSearcher(reader);
- // 命中
- Hits hits = searcher.search(query);
- if (hits.length() == 0) {
- System.out.println("hits.length=0");
- }
- /** 高亮顯示搜索的關鍵詞 */
- Document doc2 = hits.doc(0);
- //高亮處理
- String text = doc2.get("content");
- // 條件位置載體
- TermPositionVector tpv = (TermPositionVector) reader.getTermFreqVector(// 獲得條件次數載體
- 0, "content");
- // 記號流
- TokenStream ts = TokenSources.getTokenStream(tpv);
- // 格式化器
- Formatter formatter = new Formatter() {
- // 高亮條件
- public String highlightTerm(String srcText, TokenGroup g) {
- if (g.getTotalScore() <= 0) {
- return srcText;
- }
- return "<b>" + srcText + "</b>";
- }
- };
- // 高亮器
- Highlighter highlighter = new Highlighter(
- formatter,
- new QueryScorer(query)); // 查詢記錄員
- // 獲得最好的片段
- String result = highlighter.getBestFragments(ts, text, 5, "…");
- System.out.println("result:\n\t" + result);
- reader.close();
- }
- }
- package net.paoding.analysis;
- import java.io.StringReader;
- import junit.framework.TestCase;
- import net.paoding.analysis.analyzer.PaodingAnalyzer;
- import org.apache.lucene.analysis.Token;
- import org.apache.lucene.analysis.TokenStream;
- /**
- * 解析器單元測試(JUnit)
- * @author Administrator
- *
- */
- public class AnalyzerTest extends TestCase {
- protected PaodingAnalyzer analyzer = new PaodingAnalyzer();
- protected StringBuilder sb = new StringBuilder();
- /**
- * 解剖分詞
- * @param input
- * @return
- */
- protected String dissect(String input) {
- try {
- TokenStream ts = analyzer.tokenStream("", new StringReader(input));
- Token token;
- sb.setLength(0);
- while ((token = ts.next()) != null) {
- sb.append(token.termText()).append('/');
- }
- if (sb.length() > 0) {
- sb.setLength(sb.length() - 1);
- }
- System.out.println(sb.toString());
- return sb.toString();
- } catch (Exception e) {
- e.printStackTrace();
- return "error";
- }
- }
- /**
- * 斷言值: 預測的分詞
- * 結果值:詞典中的分詞
- * 解剖關鍵字 "a",返回"",表示在詞典分詞策略中字母(a)不是一個分詞
- * 斷言結果爲Green bar 表示,返回的結果與斷言中的結果相同。
- */
- public void test000() {
- String result = dissect("a");
- assertEquals("", result); // (斷言值,結果值)
- }
- /**
- *
- */
- public void test001() {
- String result = dissect("空格 a 空格");
- assertEquals("空格/空格", result);
- }
- /**
- *
- */
- public void test002() {
- String result = dissect("A座");
- assertEquals("a座", result);
- }
- /**
- *
- */
- public void test003() {
- String result = dissect("u盤");
- assertEquals("u盤", result);
- }
- public void test004() {
- String result = dissect("剛買的u盤的容量");
- assertEquals("剛/買的/u盤/容量", result); // 中文分詞效果
- }
- public void test005() {
- String result = dissect("K歌之王很好聽");
- assertEquals("k歌之王/很好/好聽", result);
- }
- // --------------------------------------------------------------
- // 僅包含詞語的句子分詞策略
- // --------------------------------------------------------------
- /**
- * 句子全由詞典詞語組成,但詞語之間沒有包含、交叉關係
- */
- public void test100() {
- String result = dissect("臺北中文國際");
- assertEquals("臺北/中文/國際", result);
- }
- /**
- * 句子全由詞典詞語組成,但詞語之間有包含關係
- */
- public void test101() {
- String result = dissect("北京首都機場");
- assertEquals("北京/首都/機場", result);
- }
- /**
- * 句子全由詞典詞語組成,但詞語之間有交叉關係
- */
- public void test102() {
- String result = dissect("東西已經拍賣了");
- assertEquals("東西/已經/拍賣/賣了", result);
- }
- /**
- * 句子全由詞典詞語組成,但詞語之間有包含、交叉等複雜關係
- */
- public void test103() {
- String result = dissect("羽毛球拍");
- assertEquals("羽毛/羽毛球/球拍", result);
- }
- // --------------------------------------------------------------
- // noise(噪音)詞彙和單字的分詞策略
- // --------------------------------------------------------------
- /**
- * 詞語之間有一個noise字(的)
- */
- public void test200() {
- String result = dissect("足球的魅力");
- assertEquals("足球/魅力", result);
- }
- /**
- * 詞語之間有一個noise詞語(因之)
- */
- public void test201() {
- String result = dissect("主人因之生氣");
- assertEquals("主人/生氣", result);
- }
- /**
- * 詞語前後分別有單字和雙字的noise詞語(與,有關)
- */
- public void test202() {
- String result = dissect("與謀殺有關");
- assertEquals("謀殺", result);
- }
- /**
- * 前有noise詞語(哪怕),後面跟隨了連續的noise單字(了,你)
- */
- public void test203() {
- String result = dissect("哪怕朋友背叛了你");
- assertEquals("朋友/背叛", result);
- }
- /**
- * 前後連續的noise詞彙(雖然,某些),詞語中有noise單字(很)
- */
- public void test204() {
- String result = dissect("雖然某些動物很兇惡");
- assertEquals("動物/兇惡", result);
- }
- // --------------------------------------------------------------
- // 詞典沒有收錄的字符串的分詞策略
- // --------------------------------------------------------------
- /**
- * 僅1個字的非詞彙串(東,西,南,北)
- */
- public void test300() {
- String result = dissect("東&&西&&南&&北");
- assertEquals("東/西/南/北", result);
- }
- /**
- * 僅兩個字的非詞彙串(古哥,谷歌,收狗,搜狗)
- */
- public void test302() {
- String result = dissect("古哥&&谷歌&&收狗&&搜狗");
- assertEquals("古哥/谷歌/收狗/搜狗", result);
- }
- /**
- * 多個字的非詞彙串
- */
- public void test303() {
- String result = dissect("這是鳥語:玉魚遇欲雨");
- assertEquals("這是/鳥語/玉魚/魚遇/遇欲/欲雨", result);
- }
- /**
- * 兩個詞語之間有一個非詞彙的字(真)
- */
- public void test304() {
- String result = dissect("朋友真背叛了你了!");
- assertEquals("朋友/真/背叛", result);
- }
- /**
- * 兩個詞語之間有一個非詞彙的字符串(盒蟹)
- */
- public void test305() {
- String result = dissect("建設盒蟹社會");
- assertEquals("建設/盒蟹/社會", result);
- }
- /**
- * 兩個詞語之間有多個非詞彙的字符串(盒少蟹)
- */
- public void test306() {
- String result = dissect("建設盒少蟹社會");
- assertEquals("建設/盒少/少蟹/社會", result);
- }
- // --------------------------------------------------------------
- // 不包含小數點的漢字數字
- // --------------------------------------------------------------
- /**
- * 單個漢字數字
- */
- public void test400() {
- String result = dissect("二");
- assertEquals("2", result);
- }
- /**
- * 兩個漢字數字
- */
- public void test61() {
- String result = dissect("五六");
- assertEquals("56", result);
- }
- /**
- * 多個漢字數字
- */
- public void test62() {
- String result = dissect("三四五六");
- assertEquals("3456", result);
- }
- /**
- * 十三
- */
- public void test63() {
- String result = dissect("十三");
- assertEquals("13", result);
- }
- /**
- * 二千
- */
- public void test65() {
- String result = dissect("二千");
- assertEquals("2000", result);
- }
- /**
- * 兩千
- */
- public void test651() {
- String result = dissect("兩千");
- assertEquals("2000", result);
- }
- /**
- * 兩千
- */
- public void test6511() {
- String result = dissect("兩千個");
- assertEquals("2000/個", result);
- }
- /**
- * 2千
- */
- public void test652() {
- String result = dissect("2千");
- assertEquals("2000", result);
- }
- /**
- *
- */
- public void test653() {
- String result = dissect("3千萬");
- assertEquals("30000000", result);
- }
- /**
- *
- */
- public void test654() {
- String result = dissect("3千萬個案例");
- assertEquals("30000000/個/案例", result);
- }
- /**
- *
- */
- public void test64() {
- String result = dissect("千萬");
- assertEquals("千萬", result);
- }
- public void test66() {
- String result = dissect("兩兩");
- assertEquals("兩兩", result);
- }
- public void test67() {
- String result = dissect("二二");
- assertEquals("22", result);
- }
- public void test68() {
- String result = dissect("2.2兩");
- assertEquals("2.2/兩", result);
- }
- public void test69() {
- String result = dissect("二兩");
- assertEquals("2/兩", result);
- }
- public void test690() {
- String result = dissect("2兩");
- assertEquals("2/兩", result);
- }
- public void test691() {
- String result = dissect("2千克");
- assertEquals("2000/克", result);
- }
- public void test692() {
- String result = dissect("2公斤");
- assertEquals("2/公斤", result);
- }
- public void test693() {
- String result = dissect("2世紀");
- assertEquals("2/世紀", result);
- }
- public void test7() {
- String result = dissect("哪怕二");
- assertEquals("2", result);
- }
- }