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