lucene中的词频

lucene in action作为action系列,确实坚持了其实用性的特色。全书花了很大的篇幅来讲解查询的解析,结果的优化和lucene应用上。很适合要做全文检索的人学习使用。但是lucen的功能决不仅仅在做搜索引擎上。如果不是最近看到一篇介绍用lucene作词频,文档统计的文章的话,我可能到现在还在为寻找一种用于专业研究的工具而苦恼。其实lucene可以很轻松地实现信息检索课中提到的要求,例如:

* 统计,实现以下功能
* (1) 统计term在整个collection中的文档频度(document frequency, DF);
(2) 统计term在整个collection中出现的词次(term frequency in whole collection);
(3) 统计term在某个文档中出现的频度(term frequency, TF);
(4) 列出term在某文档中出现的位置(position);
(5) 整个collection中文档的个数;

下面是我参考那篇文章写的一个程序:

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermEnum;
import org.apache.lucene.index.TermPositions;


public class Statistic {
/*
* 统计,实现以下功能
* (1) 统计term在整个collection中的文档频度(document frequency, DF);
(2) 统计term在整个collection中出现的词次(term frequency in whole collection);
(3) 统计term在某个文档中出现的频度(term frequency, TF);
(4) 列出term在某文档中出现的位置(position);
(5) 整个collection中文档的个数;

* */
static final Log log = LogFactory.getLog(Statistic.class);

public static void printIndex(IndexReader reader) throws Exception{
  
   //显示document数
   log.debug(new Date()+"\n");
   log.debug(reader+"\t该索引共含 "+reader.numDocs()+"篇文档\n");
  
   for(int i=0;i<reader.numDocs();i++){
    log.debug("文档"+i+":"+reader.document(i)+"\n");
   }
  
   //枚举term,获得<document, term freq, position* >信息
   TermEnum termEnum=reader.terms();
   while(termEnum.next()){
    log.debug("\n"+termEnum.term().field()+"域中出现的词语:"+termEnum.term().text());
    log.debug(" 出现改词的文档数="+termEnum.docFreq());
   
    TermPositions termPositions=reader.termPositions(termEnum.term());
    int i=0;
    int j=0;
    while(termPositions.next()){
     log.debug("\n"+(i++)+"->"+"    文章编号:"+termPositions.doc()+", 出现次数:"+termPositions.freq()+"    出现位置:");
     for(j=0;j<termPositions.freq();j++) log.debug("["+termPositions.nextPosition()+"]");
     log.debug("\n");
     }
   
    /*TermDocs termDocs=reader.termDocs(termEnum.term());
    while(termDocs.next()){
     log.debug((i++)+"->DocNo:"+termDocs.doc()+",Freq:"+termDocs.freq());
    }*/
   }
  
}

public static void main(String args[]) throws Exception{
   String index=ReadConfig.getPara("indexdir");
   IndexReader reader=IndexReader.open(index);
   printIndex(reader);
  
}
}

对资料《传记》进行统计,选取结果片断如下:

contents域中出现的词语:责任 出现改词的文档数=9


0->    文章编号:3, 出现次数:2    出现位置:[3150][3811]

1->    文章编号:6, 出现次数:7    出现位置:[715][738][1046][1846][4437][6319][6463]

2->    文章编号:7, 出现次数:2    出现位置:[4676][5856]

3->    文章编号:8, 出现次数:1    出现位置:[5824]

4->    文章编号:9, 出现次数:2    出现位置:[1840][8946]

5->    文章编号:10, 出现次数:2    出现位置:[2275][3252]

6->    文章编号:11, 出现次数:2    出现位置:[2456][6870]

7->    文章编号:12, 出现次数:3    出现位置:[6062][8090][8124]

8->    文章编号:15, 出现次数:3    出现位置:[100][1055][3078]

注:我使用的是log4j+commons logging作为输出方法(呵呵,感觉比BufferedWriter好用多了),中文分词方面选用的是基于词典的IK_CAnalyzer分词类,效果较好,基本可以满足使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值