Lucene2.2 + MMAnalyzer 1.5 实现 中文分词 并排序

代码:

import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import jeasy.analysis.MMAnalyzer; /** * 此次测试使用的是Lucene2.2 * @author 李晗 * */ public class Test { public static void main(String[] args) { String text = "看了我爸爸就心情不好,我快得忧郁病了。说说我爸爸的一些事吧,也许从一两件简单的生活琐事,你会觉得我太计较,但是你不知道,每天都有几个意想不到的”惊喜“给你,你的心情真的可以经受考验吗?我实在受不了了。也许你们会觉得我很不孝顺,但是没有经历过的人不会明白 周日回家,发现厨房有袋泰国香米,觉得奇怪,米还有很多呢,怎么又买了一袋呢。本想不问,可还是忍不住,问在客厅里盯着电视一动不动的爸爸,“怎么买了一袋米呢?”他赶紧从沙发上起身,说“是啊,我也不知道怎么会有袋米,有个野拿来的,我以为是你叫人送上来的‘ 接着他走到餐柜上拿了一张小票看。我在脑海里快速搜索,难道是W,有时老公会让他帮忙买米,但是这次不对啊,老公出差了,而且家里还有很多米,况且每次让他帮忙买都是我们自己拿回家的。结论:肯定是别人送错了。本想不管了,反正米是要吃的,就留着吃吧,赶紧到厨房做饭了,顺手拿来小票看了一眼,哗,100元,这么贵,再看看是楼下超市,还有电话。太贵了,我们家一般吃东北大米。马上打电话让他们来拿回去。真是的,拿不准,就不会打个电话问吗?顺便说一下,连打个电话都懒。 昨天中午买了烧腊外卖带回家,回家比较晚了,配了有几小袋的酱汁和烧鹅酱,撕开倒在小碟子上,几个小空袋(比方便面的味包小一半),就放在了打开的一次性饭盒盖上。时间晚了,没有把食物空出来放在自家的碟子上。没吃完,剩一半,可以留晚上吃。吃完赶紧去上班,爸爸收拾洗碗。晚上回家,赶紧做菜,把桌上中午吃剩的烧鹅饭盒直接放进微波炉加热,完了开饭,打开饭盒,一开,天呐,那几个空的酱油袋好好地呆在烧鹅上面呢。我的天啊,忍,忍不住,我说,爸爸,怎么这些空的酱油袋还放在里面不扔掉呢?他在看电视,好象楞了一下,说:恩,我以为你还要嘛” 。大多数时候,我已经修炼得不会继续说话的了,因为说多一句,他都会生气,或者和我争吵,认为我很挑剔,容不下他。但是这次我忍不住了,我说;都空的还会有什么用?“ 。我的语气都是很平和的。可是心里真的是不开心。他这个人真的很蠢,而且做什么事情都是非常随便,不用脑的,其实有些事情根本就不需要用脑,很简单的事,可是他经常都会让你大吃一惊,气堵胸口。 林林总总,对着这样的一个人,我真的觉得他没死我就会先死,虽然他是我爸爸,可是他的很多不良习惯我真的很难忍受。 碰到这样的父母,做子女的该怎么办呢?媒体,报纸,天天说子女要理解父母,孝顺父母,多陪父母.......我都挺晕的,很多时候你想跟他们说话,可是无话可说,各种习惯又合不来......怎么不说说父母也应该进步,提高自我,不要把自己和子女,和社会的差距拉得太大呢? 我的想法是,父母应该要孝顺,但是不一定要同住,否则大家都痛苦。敬而远之,大家关系还好些,心情也好些"; MMAnalyzer analyzer = new MMAnalyzer(); Map<String,Integer> map = new HashMap<String,Integer>(); try { String[] str = analyzer.segment(text, " ").split(" "); System.out.println("词数:"+str.length); for(int i=0;i<str.length;i++){ String temp = str[i]; int tempCount=0; for(int j=0;j<str.length;j++){ if(temp.equals(str[j])) tempCount++; } map.put(temp, tempCount); } } catch (IOException e) { e.printStackTrace(); } System.out.println("map size:"+map.size()); Set<Entry<String, Integer>> set = map.entrySet(); Iterator<Entry<String, Integer>> itor = set.iterator(); while(itor.hasNext()) { Entry<String, Integer> entry = itor.next(); if(1==entry.getValue()) itor.remove(); } List<Map.Entry<String, Integer>> list = sortMap(map); //排序后 for (int i = 0; i < list.size(); i++) { System.out.print(list.get(i).getKey()+"、"); } System.out.println(); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } } //排序包含分词的Map public static List<Map.Entry<String, Integer>> sortMap(Map<String,Integer> map){ List<Map.Entry<String, Integer>> infoIds = new ArrayList<Map.Entry<String, Integer>>(map.entrySet()); for(int i=0;i<infoIds.size();i++){ if(infoIds.get(i).getKey().length()==1){//去除单个字 infoIds.remove(i); } } //排序 Collections.sort(infoIds, new Comparator<Map.Entry<String, Integer>>() { public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { return (o2.getValue() - o1.getValue()); //return (o1.getKey()).toString().compareTo(o2.getKey()); } }); return infoIds; } }

运行结果:

词数:486
map size:338
说、爸爸、父母、真的、怎么、觉得、但是、小、赶紧、回家、饭盒、让他、子女、烧鹅、电话、就、很多、心情、忍不住、买了、一半、拿来、好些、厨房、天、而且、可是他、帮忙、吃完、一袋、用脑、说话、是你、晚上、可是、看了、都会、酱油、这样、碟子、可以、电视、也许、几个、一下、打开、都是、空的、不会、没有、这次、还有、放在、本想、孝顺、简单、大家、自己、晚了、时候、
说=7
爸爸=6
父母=5
真的=4
怎么=4
觉得=4
但是=4
小=4
赶紧=4
回家=4
饭盒=3
让他=3
子女=3
烧鹅=3
电话=3
就=3
很多=3
心情=3
忍不住=3
买了=3
一半=2
拿来=2
好些=2
厨房=2
天=2
而且=2
可是他=2
帮忙=2
吃完=2
一袋=2
用脑=2
说话=2
是你=2
晚上=2
可是=2
看了=2
都会=2
酱油=2
这样=2
碟子=2
可以=2
电视=2
也许=2
几个=2
一下=2
打开=2
都是=2
空的=2
不会=2
没有=2
这次=2
还有=2
放在=2
本想=2
孝顺=2
简单=2
大家=2
自己=2
晚了=2
时候=2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该组件免费安装使用传播,无限制商业应用,但暂不开源,也不提供任何保证 分词效率: 第一次分词需要1-2秒(读取词典),之后速度基本与Lucene自带分词持平 运行环境: Lucene 1.9+ 内存消耗: 30M+ 1.4.0 —— 2006-08-21 增加词典的动态扩展能力 1.3.3 —— 2006-07-23 修正无法多次增加词典的问题 1.3.2 —— 2006-07-03 修正细粒度分词错误的问题 1.3.1 —— 2006-06-23 修正在某些情况下分词遗漏的问题 1.3 —— 2006-06-22 实现了词尾消歧算法中第一层的过滤 增加日期时间的匹配 1.2.2 —— 2006-06-13 完善了中英文噪声词典 1.2.1 —— 2006-06-10 修正中文数字成语无法识别的问题 1.2 —— 2006-06-08 增加中文数字的匹配(如:二零零六) 数量词采用“n”作为数字通配符 优化词典结构以便修改调整 1.1 —— 2006-06-06 增加扩展词典的静态读取方法 1.0.1 —— 2006-06-02 修正无法识别生僻字的问题 1.0 —— 2006-05-29 支持英文、数字、中文(简体)混合分词 常用的数量和人名的匹配 超过22万词的词库整理 实现正向最大匹配算法 //采用正向最大匹配的中文分词算法,相当于分词粒度等于0 MMAnalyzer analyzer = new MMAnalyzer(); //参数为分词粒度:当字数等于或超过该参数,且能成词,该词就被切分出来 MMAnalyzer analyzer = new MMAnalyzer(2); //增加一个新词典,采用每行一个词的读取方式 MMAnalyzer.addDictionary(reader); //增加一个新词 MMAnalyzer.addWord(newWord); package demo.analysis; import java.io.IOException; import jeasy.analysis.MMAnalyzer; public class Segment { public static void main(String[] args) { String text = "据路透社报道,印度尼西亚社会事务部一官员星期二(29日)表示," + "日惹市附近当地时间27日晨5时53分发生的里氏6.2级地震已经造成至少5427人死亡," + "20000余人受伤,近20万人无家可归。"; MMAnalyzer analyzer = new MMAnalyzer(); try { System.out.println(analyzer.segment(text, " | ")); } catch (IOException e) { e.printStackTrace(); } } } 生成效果: 据 | 路透社 | 报道 | 印度尼西亚 | 社会 | 事务 | 部 | 官员 | 星期二 | 29日 | 表示 | 日惹 | 市 | 附近 | 当地时间 | 27日 | 晨 | 5时 | 53分 | 发生 | 里氏 | 6.2级 | 地震 | 已经 | 造成 | 至少 | 5427人 | 死亡 | 20000 | 余人 | 受伤 | 近 | 20万人 | 无家可归 | package demo.analysis; import jeasy.analysis.MMAnalyzer; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; 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.store.Directory; import org.apache.lucene.store.RAMDirectory; public class Segment { public static void main(String[] args) { String fieldName = "text"; String text = "据路透社报道,印度尼西亚社会事务部一官员星期二(29日)表示," + "日惹市附近当地时间27日晨5时53分发生的里氏6.2级地震已经造成至少5427人死亡," + "20000余人受伤,近20万人无家可归。"; //检索内容 //采用正向最大匹配的中文分词算法 Analyzer analyzer = new MMAnalyzer(); Directory directory = new RAMDirectory(); //Directory directory = FSDirectory.getDirectory("/tmp/testindex", true); try { IndexWriter iwriter = new IndexWriter(directory, analyzer, true); iwriter.setMaxFieldLength(25000); Document doc = new Document(); doc.add(new Field(fieldName, text, Field.Store.YES, Field.Index.TOKENIZED)); iwriter.addDocument(doc); iwriter.close(); IndexSearcher isearcher = new IndexSearcher(directory); QueryParser parser = new QueryParser(fieldName, analyzer); Query query = parser.parse("印度尼西亚 6.2级地震");//检索词 Hits hits = isearcher.search(query); System.out.println("命中:" + hits.length()); for (int i = 0; i < hits.length(); i++) { Document hitDoc = hits.doc(i); System.out.println("内容:" + hitDoc.get(fieldName)); } isearcher.close(); directory.close(); } catch (Exception e) { e.printStackTrace(); } } } 生成效果: 命中:1 内容:据路透社报道,印度尼西亚社会事务部一官员星期二(29日)表示,日惹市附近当地时间27日晨5时53分发生 的里氏6.2级地震已经造成至少5427人死亡,20000余人受伤,近20万人无家可归。 package demo.analysis; import jeasy.analysis.MMAnalyzer; 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.highlight.Highlighter; import org.apache.lucene.search.highlight.QueryScorer; import org.apache.lucene.search.highlight.TokenSources; import org.apache.lucene.store.Directory; import org.apache.lucene.store.RAMDirectory; public class Segment { public static void main(String[] args) { String fieldName = "text"; String text = "据路透社报道,印度尼西亚社会事务部一官员星期二(29日)表示," + "日惹市附近当地时间27日晨5时53分发生的里氏6.2级地震已经造成至少5427人死亡," + "20000余人受伤,近20万人无家可归。"; //检索内容 //采用正向最大匹配的中文分词算法 Analyzer analyzer = new MMAnalyzer(); Directory directory = new RAMDirectory(); //Directory directory = FSDirectory.getDirectory("/tmp/testindex", true); try { IndexWriter iwriter = new IndexWriter(directory, analyzer, true); iwriter.setMaxFieldLength(25000); Document doc = new Document(); doc.add(new Field(fieldName, text, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); iwriter.addDocument(doc); iwriter.close(); IndexSearcher isearcher = new IndexSearcher(directory); QueryParser parser = new QueryParser(fieldName, analyzer); Query query = parser.parse("印度尼西亚 6.2级地震");//检索词 Hits hits = isearcher.search(query); System.out.println("命中:" + hits.length()); Highlighter highlighter = new Highlighter(new QueryScorer(query)); for (int i = 0; i < hits.length(); i++) { text = hits.doc(i).get(fieldName); TermPositionVector tpv = (TermPositionVector) IndexReader.open( directory).getTermFreqVector(hits.id(i), fieldName); TokenStream tokenStream = TokenSources.getTokenStream(tpv); String result = highlighter.getBestFragments(tokenStream, text, 3, "..."); System.out.println("内容:" + result); } isearcher.close(); directory.close(); } catch (Exception e) { e.printStackTrace(); } } } 生成效果: 命中:1 内容:据路透社报道,<B>印度尼西亚</B>社会事务部一官员星期二(29日)表示,日惹市附近当地时间27日晨5时53分发生的 里氏<B>6.2级</B><B>地震</B>已经造成至少5427人死亡,20000余人受伤,近20万人无家可归
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值