使用IKAnalyzer分词计算文章关键字并分享几个分词词典

    这应该是我第二次写IK中文分词的相关东西了。话说IK真心好用,最开始就用过IK的搜索后来又用它和solr结合使用。

    关于IK可以参考下官方文档的介绍,使用配置也有相关的pdf文档。http://www.oschina.net/p/ikanalyzer

    今天仅仅使用到了IK的分词功能。所以代码很简单,我就直接贴上来了。

    这个代码主要是对传入的参数进行分词,并统计好每个次的频率。代码如下:  

public static Map getTextDef(String text) throws IOException {
        Map<String, Integer> wordsFren=new HashMap<String, Integer>();
        IKSegmenter ikSegmenter = new IKSegmenter(new StringReader(text), true);
        Lexeme lexeme;
        while ((lexeme = ikSegmenter.next()) != null) {
            if(lexeme.getLexemeText().length()>1){
                if(wordsFren.containsKey(lexeme.getLexemeText())){
                    wordsFren.put(lexeme.getLexemeText(),wordsFren.get(lexeme.getLexemeText())+1);
                }else {
                    wordsFren.put(lexeme.getLexemeText(),1);
                }
            }
        }
        return wordsFren;
    }

    代码很简单,主要介绍下IK中的类,IKSegmenter是分词的主要类,其参数分别是分词的句子或者文章,后面的参数是是否开启智能模式,不开启就按最小词义分。

    分词的结果是Lexeme这个类,用其中的getLexemeText()方法就能取出相关的分词结果。

    接下来是计算词频,将分词结果和出现次数放到一个map结构中,map的value对应了词的出现次数。这里注意一下,我只记录两个字及两个字以上的分词结果。

 

public static void sortSegmentResult(Map<String,Integer> wordsFrenMaps,int topWordsCount){
        System.out.println("排序前:================");
        Iterator<Map.Entry<String,Integer>> wordsFrenMapsIterator=wordsFrenMaps.entrySet().iterator();
        while (wordsFrenMapsIterator.hasNext()){
            Map.Entry<String,Integer> wordsFrenEntry=wordsFrenMapsIterator.next();
            System.out.println(wordsFrenEntry.getKey()+"             的次数为"+wordsFrenEntry.getValue());
        }

        List<Map.Entry<String, Integer>> wordFrenList = new ArrayList<Map.Entry<String, Integer>>(wordsFrenMaps.entrySet());
        Collections.sort(wordFrenList, new Comparator<Map.Entry<String, Integer>>() {
            public int compare(Map.Entry<String, Integer> obj1, Map.Entry<String, Integer> obj2) {
                return obj2.getValue() - obj1.getValue();
            }
        });
        System.out.println("排序后:================");
        for(int i=0;i<topWordsCount&&i<wordFrenList.size();i++){
            Map.Entry<String,Integer> wordFrenEntry=wordFrenList.get(i);
            if(wordFrenEntry.getValue()>1){
                System.out.println(wordFrenEntry.getKey()+"             的次数为"+wordFrenEntry.getValue());
            }
        }
    }

    这个方法主要对分词结果及词频按照出现次数排序,没有自己去写实现,主要借用了collections的sort方法。

    测试方法如下:

public static void main(String args[]) throws IOException {

        String text = "IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出 了3个大版本。最初,它是以开源项目 Lucene为应用主体的,结合词典分词和文法分析算法的中文分词组件。新版本的IKAnalyzer3.0则发展为 面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。\n" +
                "\n" +
                "IKAnalyzer3.0特性:\n" +
                "\n" +
                "采用了特有的“正向迭代最细粒度切分算法“,具有60万字/秒的高速处理能力。\n" +
                "\n" +
                "采用了多子处理器分析模式,支持:英文字母(IP地址、Email、URL)、数字(日期,常用中文数量词,罗马数字,科学计数法),中文词汇(姓名、地名处理)等分词处理。\n" +
                "\n" +
                "优化的词典存储,更小的内存占用。支持用户词典扩展定义\n" +
                "\n" +
                "针对Lucene全文检索优化的查询分析器IKQueryParser(作者吐血推荐);采用歧义分析算法优化查询关键字的搜索排列组合,能极大的提高Lucene检索的命中率。";
        int topWordsCount=3;
        Map<String,Integer> wordsFrenMaps=getTextDef(text);
        sortSegmentResult(wordsFrenMaps,topWordsCount);


    }
输出结果为:


加载扩展词典:ikdict/ext.dic
加载扩展停止词典:ikdict/english_stopword.dic
加载扩展停止词典:ikdict/chinese_stopword.dic
排序前:================
ikanalyzer3.0             的次数为2
开源             的次数为2
开发             的次数为1
姓名             的次数为1
lucene             的次数为5
内存             的次数为1
词汇             的次数为1
支持             的次数为2
英文字母             的次数为1
查询             的次数为2
面向             的次数为1
采用             的次数为1
12月             的次数为1
推荐             的次数为1
ikanalyzer             的次数为2
地名             的次数为1
默认             的次数为1
提供             的次数为1
特性             的次数为1
地址             的次数为1
中文             的次数为4
文法             的次数为1
组件             的次数为2
新版本             的次数为1
吐血             的次数为1
检索             的次数为2
全文             的次数为1
常用             的次数为1
公用             的次数为1
分析器             的次数为1
项目             的次数为2
存储             的次数为1
数量词             的次数为1
处理器             的次数为1
工具包             的次数为1
占用             的次数为1
计数             的次数为1
分析             的次数为3
版本             的次数为1
正向             的次数为1
url             的次数为1
用了             的次数为2
迭代             的次数为1
搜索             的次数为1
模式             的次数为1
email             的次数为1
关键字             的次数为1
日期             的次数为1
扩展             的次数为1
提高             的次数为1
ikqueryparser             的次数为1
能力             的次数为1
3个             的次数为1
词典             的次数为3
排列组合             的次数为1
更小             的次数为1
定义             的次数为1
科学             的次数为1
高速             的次数为1
轻量级             的次数为1
优化             的次数为4
细粒度             的次数为1
2006年             的次数为1
发展为             的次数为1
多子             的次数为1
命中率             的次数为1
立于             的次数为1
数字             的次数为1
万字             的次数为1
60             的次数为1
特有             的次数为1
罗马数字             的次数为1
推出             的次数为2
用户             的次数为1
1.0版             的次数为1
ip             的次数为1
算法             的次数为3
分词             的次数为5
歧义             的次数为1
作者             的次数为1
java             的次数为2
语言             的次数为1
主体             的次数为1
最初             的次数为1
切分             的次数为1
排序后:================
lucene             的次数为5
分词             的次数为5
中文             的次数为4

这里面要注意一下,IK本身有一个文件叫IKAnalyzer.cfg.xml

这个文件可以自己配置词典,词典有两种分别是ext_dict及ext_stopwords,其中ext_dict主要定义了一些关键字,这些关键字不会被分词分开,ext_stopwords主要配置停止词,什么是停止词呢?比如“的”,“得”,“我”这些没有具体意义但是又出现特别多的词就不应该作为关键字词出现,所以在分词的时候要把这些词过滤掉。


<properties>  
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典-->
	<entry key="ext_dict">ikdict/ext.dic;</entry>

	<!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords">ikdict/english_stopword.dic;ikdict/chinese_stopword.dic</entry>

</properties>
这里我主要配置了3个词典,其中的两个停止词分别是英文和中文的。网上有很多词典,但是都不是太全,我收集了一些,汇总了一下分享给大家。


但是OSC好像没有附件可以传。。。放到代码分享中了,用的自取,http://www.oschina.net/code/snippet_195637_22628

其中中文停止词4545个,英文停止词1434个,数据库相关词汇1692个。

总结一下,最近正在研究关键字及摘要自动生成,这里主要介绍了使用IK分词并统计词频,并分享了相关的词典。但是计算关键字单靠这样的分词统计词频还是不管用的,最近在研究TFIDF算法,后面实现成功了再和大家分享一下。


转载于:https://my.oschina.net/zimingforever/blog/142000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值