Paoding Analyzer

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,以免一时疏忽将重要数据丢失。

 

Java代码  收藏代码
  1. package net.paoding.analysis;  
  2.   
  3. import net.paoding.analysis.analyzer.PaodingAnalyzer;  
  4.   
  5. import org.apache.lucene.analysis.Analyzer;  
  6. import org.apache.lucene.analysis.TokenStream;  
  7. import org.apache.lucene.document.Document;  
  8. import org.apache.lucene.document.Field;  
  9. import org.apache.lucene.index.IndexReader;  
  10. import org.apache.lucene.index.IndexWriter;  
  11. import org.apache.lucene.index.TermPositionVector;  
  12. import org.apache.lucene.queryParser.QueryParser;  
  13. import org.apache.lucene.search.Hits;  
  14. import org.apache.lucene.search.IndexSearcher;  
  15. import org.apache.lucene.search.Query;  
  16. import org.apache.lucene.search.Searcher;  
  17. import org.apache.lucene.search.highlight.Formatter;  
  18. import org.apache.lucene.search.highlight.Highlighter;  
  19. import org.apache.lucene.search.highlight.QueryScorer;  
  20. import org.apache.lucene.search.highlight.TokenGroup;  
  21. import org.apache.lucene.search.highlight.TokenSources;  
  22.   
  23. /** 
  24.  * 创建索引库 
  25.  * @author Administrator 
  26.  * 
  27.  */  
  28. public class CreateIndexLibTest {  
  29.     public static void main(String[] args) throws Exception {  
  30.           
  31.         /** 创建分词 */  
  32.         // 词典目录  
  33.         String path = "D:\\Java\\paoding_analyzer\\dic";  
  34.         // 庖丁解牛中文分词器  
  35.         Analyzer analyzer = new PaodingAnalyzer();  
  36.         // 索引书写器  
  37.         IndexWriter writer = new IndexWriter(path, analyzer, true);  
  38.         // 文档  
  39.         Document doc = new Document();  
  40.         // 字段  
  41.         Field field = new Field(  
  42.                 "content",                                  // name  
  43.                 "你好,世界!",                               // value  
  44.                 Field.Store.YES,                            // store  
  45.                 Field.Index.TOKENIZED,                      // index  
  46.                 Field.TermVector.WITH_POSITIONS_OFFSETS);   // termVector  
  47.         doc.add(field);             // 文档添加字段  
  48.         writer.addDocument(doc);    // 索引书写器添加文档  
  49.         writer.close();  
  50.         System.out.println("Indexed success!");  
  51.            
  52.         /** 搜索关键词 */  
  53.         // 索引读取器  
  54.         IndexReader reader = IndexReader.open(path);  
  55.         // 查询解析器  
  56.         QueryParser parser = new QueryParser("content", analyzer);  
  57.         Query query = parser.parse("你好");   // 解析  
  58.         // 搜索器  
  59.         Searcher searcher = new IndexSearcher(reader);  
  60.         // 命中  
  61.         Hits hits = searcher.search(query);  
  62.         if (hits.length() == 0) {  
  63.             System.out.println("hits.length=0");  
  64.         }  
  65.           
  66.         /** 高亮显示搜索的关键词 */     
  67.         Document doc2 = hits.doc(0);  
  68.         //高亮处理  
  69.         String text = doc2.get("content");  
  70.         // 条件位置载体  
  71.         TermPositionVector tpv = (TermPositionVector) reader.getTermFreqVector(// 获得条件次数载体  
  72.                         0"content");  
  73.         // 记号流  
  74.         TokenStream ts = TokenSources.getTokenStream(tpv);  
  75.         // 格式化器  
  76.         Formatter formatter = new Formatter() {  
  77.             // 高亮条件  
  78.             public String highlightTerm(String srcText, TokenGroup g) {  
  79.                 if (g.getTotalScore() <= 0) {  
  80.                     return srcText;  
  81.                 }  
  82.                 return "<b>" + srcText + "</b>";  
  83.             }  
  84.         };  
  85.         // 高亮器  
  86.         Highlighter highlighter = new Highlighter(  
  87.                 formatter,   
  88.                 new QueryScorer(query));    // 查询记录员  
  89.         // 获得最好的片段  
  90.         String result = highlighter.getBestFragments(ts, text, 5"…");  
  91.         System.out.println("result:\n\t" + result);  
  92.         reader.close();  
  93.   
  94.     }  
  95. }  

 

 

 

Java代码  收藏代码
  1. package net.paoding.analysis;  
  2.   
  3. import java.io.StringReader;  
  4.   
  5. import junit.framework.TestCase;  
  6. import net.paoding.analysis.analyzer.PaodingAnalyzer;  
  7.   
  8. import org.apache.lucene.analysis.Token;  
  9. import org.apache.lucene.analysis.TokenStream;  
  10. /** 
  11.  * 解析器单元测试(JUnit) 
  12.  * @author Administrator 
  13.  * 
  14.  */  
  15. public class AnalyzerTest extends TestCase {  
  16.   
  17.     protected PaodingAnalyzer analyzer = new PaodingAnalyzer();  
  18.   
  19.     protected StringBuilder sb = new StringBuilder();  
  20.   
  21.     /** 
  22.      * 解剖分词 
  23.      * @param input 
  24.      * @return 
  25.      */  
  26.     protected String dissect(String input) {  
  27.         try {  
  28.             TokenStream ts = analyzer.tokenStream(""new StringReader(input));  
  29.             Token token;  
  30.             sb.setLength(0);  
  31.             while ((token = ts.next()) != null) {  
  32.                 sb.append(token.termText()).append('/');  
  33.             }  
  34.             if (sb.length() > 0) {  
  35.                 sb.setLength(sb.length() - 1);  
  36.             }  
  37.             System.out.println(sb.toString());  
  38.             return sb.toString();  
  39.         } catch (Exception e) {  
  40.             e.printStackTrace();  
  41.             return "error";  
  42.         }  
  43.     }  
  44.   
  45.     /** 
  46.      * 断言值: 预测的分词 
  47.      * 结果值:词典中的分词 
  48.      * 解剖关键字 "a",返回"",表示在词典分词策略中字母(a)不是一个分词 
  49.      * 断言结果为Green bar 表示,返回的结果与断言中的结果相同。 
  50.      */  
  51.     public void test000() {  
  52.         String result = dissect("a");  
  53.         assertEquals("", result);       // (断言值,结果值)  
  54.     }  
  55.   
  56.     /** 
  57.      * 
  58.      */  
  59.     public void test001() {  
  60.         String result = dissect("空格 a 空格");  
  61.         assertEquals("空格/空格", result);  
  62.     }  
  63.   
  64.     /** 
  65.      * 
  66.      */  
  67.     public void test002() {  
  68.         String result = dissect("A座");  
  69.         assertEquals("a座", result);  
  70.     }  
  71.       
  72.     /** 
  73.      * 
  74.      */  
  75.     public void test003() {  
  76.         String result = dissect("u盘");  
  77.         assertEquals("u盘", result);  
  78.     }  
  79.   
  80.     public void test004() {  
  81.         String result = dissect("刚买的u盘的容量");  
  82.         assertEquals("刚/买的/u盘/容量", result); // 中文分词效果  
  83.     }  
  84.       
  85.     public void test005() {  
  86.         String result = dissect("K歌之王很好听");  
  87.         assertEquals("k歌之王/很好/好听", result);  
  88.     }  
  89.     // --------------------------------------------------------------  
  90.     // 仅包含词语的句子分词策略  
  91.     // --------------------------------------------------------------  
  92.   
  93.     /** 
  94.      * 句子全由词典词语组成,但词语之间没有包含、交叉关系 
  95.      */  
  96.     public void test100() {  
  97.         String result = dissect("台北中文国际");  
  98.         assertEquals("台北/中文/国际", result);  
  99.     }  
  100.   
  101.     /** 
  102.      * 句子全由词典词语组成,但词语之间有包含关系 
  103.      */  
  104.     public void test101() {  
  105.         String result = dissect("北京首都机场");  
  106.         assertEquals("北京/首都/机场", result);  
  107.     }  
  108.   
  109.     /** 
  110.      * 句子全由词典词语组成,但词语之间有交叉关系 
  111.      */  
  112.     public void test102() {  
  113.         String result = dissect("东西已经拍卖了");  
  114.         assertEquals("东西/已经/拍卖/卖了", result);  
  115.     }  
  116.   
  117.     /** 
  118.      * 句子全由词典词语组成,但词语之间有包含、交叉等复杂关系 
  119.      */  
  120.     public void test103() {  
  121.         String result = dissect("羽毛球拍");  
  122.         assertEquals("羽毛/羽毛球/球拍", result);  
  123.     }  
  124.   
  125.     // --------------------------------------------------------------  
  126.     // noise(噪音)词汇和单字的分词策略  
  127.     // --------------------------------------------------------------  
  128.   
  129.     /** 
  130.      * 词语之间有一个noise字(的) 
  131.      */  
  132.     public void test200() {  
  133.         String result = dissect("足球的魅力");  
  134.         assertEquals("足球/魅力", result);  
  135.     }  
  136.   
  137.     /** 
  138.      * 词语之间有一个noise词语(因之) 
  139.      */  
  140.     public void test201() {  
  141.         String result = dissect("主人因之生气");  
  142.         assertEquals("主人/生气", result);  
  143.     }  
  144.   
  145.     /** 
  146.      * 词语前后分别有单字和双字的noise词语(与,有关) 
  147.      */  
  148.     public void test202() {  
  149.         String result = dissect("与谋杀有关");  
  150.         assertEquals("谋杀", result);  
  151.     }  
  152.   
  153.     /** 
  154.      * 前有noise词语(哪怕),后面跟随了连续的noise单字(了,你) 
  155.      */  
  156.     public void test203() {  
  157.         String result = dissect("哪怕朋友背叛了你");  
  158.         assertEquals("朋友/背叛", result);  
  159.     }  
  160.   
  161.     /** 
  162.      * 前后连续的noise词汇(虽然,某些),词语中有noise单字(很) 
  163.      */  
  164.     public void test204() {  
  165.         String result = dissect("虽然某些动物很凶恶");  
  166.         assertEquals("动物/凶恶", result);  
  167.     }  
  168.   
  169.     // --------------------------------------------------------------  
  170.     // 词典没有收录的字符串的分词策略  
  171.     // --------------------------------------------------------------  
  172.   
  173.       
  174.     /** 
  175.      * 仅1个字的非词汇串(东,西,南,北) 
  176.      */  
  177.     public void test300() {  
  178.         String result = dissect("东&&西&&南&&北");  
  179.         assertEquals("东/西/南/北", result);  
  180.     }  
  181.   
  182.       
  183.     /** 
  184.      * 仅两个字的非词汇串(古哥,谷歌,收狗,搜狗) 
  185.      */  
  186.     public void test302() {  
  187.         String result = dissect("古哥&&谷歌&&收狗&&搜狗");  
  188.         assertEquals("古哥/谷歌/收狗/搜狗", result);  
  189.     }  
  190.       
  191.     /** 
  192.      * 多个字的非词汇串 
  193.      */  
  194.     public void test303() {  
  195.         String result = dissect("这是鸟语:玉鱼遇欲雨");  
  196.         assertEquals("这是/鸟语/玉鱼/鱼遇/遇欲/欲雨", result);  
  197.     }  
  198.       
  199.     /** 
  200.      * 两个词语之间有一个非词汇的字(真) 
  201.      */  
  202.     public void test304() {  
  203.         String result = dissect("朋友真背叛了你了!");  
  204.         assertEquals("朋友/真/背叛", result);  
  205.     }  
  206.       
  207.     /** 
  208.      * 两个词语之间有一个非词汇的字符串(盒蟹) 
  209.      */  
  210.     public void test305() {  
  211.         String result = dissect("建设盒蟹社会");  
  212.         assertEquals("建设/盒蟹/社会", result);  
  213.     }  
  214.       
  215.     /** 
  216.      * 两个词语之间有多个非词汇的字符串(盒少蟹) 
  217.      */  
  218.     public void test306() {  
  219.         String result = dissect("建设盒少蟹社会");  
  220.         assertEquals("建设/盒少/少蟹/社会", result);  
  221.     }  
  222.   
  223.     // --------------------------------------------------------------  
  224.     // 不包含小数点的汉字数字  
  225.     // --------------------------------------------------------------  
  226.   
  227.   
  228.     /** 
  229.      * 单个汉字数字 
  230.      */  
  231.     public void test400() {  
  232.         String result = dissect("二");  
  233.         assertEquals("2", result);  
  234.     }  
  235.   
  236.     /** 
  237.      * 两个汉字数字 
  238.      */  
  239.     public void test61() {  
  240.         String result = dissect("五六");  
  241.         assertEquals("56", result);  
  242.     }  
  243.   
  244.     /** 
  245.      * 多个汉字数字 
  246.      */  
  247.     public void test62() {  
  248.         String result = dissect("三四五六");  
  249.         assertEquals("3456", result);  
  250.     }  
  251.   
  252.     /** 
  253.      * 十三 
  254.      */  
  255.     public void test63() {  
  256.         String result = dissect("十三");  
  257.         assertEquals("13", result);  
  258.     }  
  259.   
  260.     /** 
  261.      * 二千 
  262.      */  
  263.     public void test65() {  
  264.         String result = dissect("二千");  
  265.         assertEquals("2000", result);  
  266.     }  
  267.   
  268.     /** 
  269.      * 两千 
  270.      */  
  271.     public void test651() {  
  272.         String result = dissect("两千");  
  273.         assertEquals("2000", result);  
  274.     }  
  275.     /** 
  276.      * 两千 
  277.      */  
  278.     public void test6511() {  
  279.         String result = dissect("两千个");  
  280.         assertEquals("2000/个", result);  
  281.     }  
  282.   
  283.     /** 
  284.      * 2千 
  285.      */  
  286.     public void test652() {  
  287.         String result = dissect("2千");  
  288.         assertEquals("2000", result);  
  289.     }  
  290.       
  291.     /** 
  292.      *  
  293.      */  
  294.     public void test653() {  
  295.         String result = dissect("3千万");  
  296.         assertEquals("30000000", result);  
  297.     }  
  298.       
  299.     /** 
  300.      *  
  301.      */  
  302.     public void test654() {  
  303.         String result = dissect("3千万个案例");  
  304.         assertEquals("30000000/个/案例", result);  
  305.     }  
  306.   
  307.   
  308.     /** 
  309.      *  
  310.      */  
  311.     public void test64() {  
  312.         String result = dissect("千万");  
  313.         assertEquals("千万", result);  
  314.     }  
  315.   
  316.     public void test66() {  
  317.         String result = dissect("两两");  
  318.         assertEquals("两两", result);  
  319.     }  
  320.   
  321.     public void test67() {  
  322.         String result = dissect("二二");  
  323.         assertEquals("22", result);  
  324.     }  
  325.   
  326.     public void test68() {  
  327.         String result = dissect("2.2两");  
  328.         assertEquals("2.2/两", result);  
  329.     }  
  330.   
  331.     public void test69() {  
  332.         String result = dissect("二两");  
  333.         assertEquals("2/两", result);  
  334.     }  
  335.   
  336.   
  337.     public void test690() {  
  338.         String result = dissect("2两");  
  339.         assertEquals("2/两", result);  
  340.     }  
  341.   
  342.     public void test691() {  
  343.         String result = dissect("2千克");  
  344.         assertEquals("2000/克", result);  
  345.     }  
  346.   
  347.     public void test692() {  
  348.         String result = dissect("2公斤");  
  349.         assertEquals("2/公斤", result);  
  350.     }  
  351.   
  352.     public void test693() {  
  353.         String result = dissect("2世纪");  
  354.         assertEquals("2/世纪", result);  
  355.     }  
  356.   
  357.     public void test7() {  
  358.         String result = dissect("哪怕二");  
  359.         assertEquals("2", result);  
  360.     }  
  361.   
  362. }  

 

发布了60 篇原创文章 · 获赞 18 · 访问量 38万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章