现在的位置: 首页 > 综合 > 正文

lucene 关键词高亮显示

2013年07月10日 ⁄ 综合 ⁄ 共 6258字 ⁄ 字号 评论关闭

 

使用Lucene自带的Highlighter就可以实现对原始文件摘要的提取工作。Highlighter类有一个getBestFragment方法,这个方法有多个重载的方法,其中,使用:

public final String getBestFragment(Analyzer analyzer, String fieldName,String text)

就可以提取摘要,它实现了从指定的原始文件中,提取检索关键字出现频率最高的一段文字作为摘要,默认情况下提取100个字符,同时加上自定义的高亮显示代码,又可实现关键字高亮显示。

测试程序如下所示:

  1. package org.shirdrn.lucene.learn.digest;
  2. import java.io.IOException;
  3. import net.teamhot.lucene.ThesaurusAnalyzer;
  4. import org.apache.lucene.analysis.Analyzer;
  5. import org.apache.lucene.document.Document;
  6. import org.apache.lucene.document.Field;
  7. import org.apache.lucene.index.CorruptIndexException;
  8. import org.apache.lucene.index.IndexWriter;
  9. import org.apache.lucene.queryParser.ParseException;
  10. import org.apache.lucene.queryParser.QueryParser;
  11. import org.apache.lucene.search.Hits;
  12. import org.apache.lucene.search.IndexSearcher;
  13. import org.apache.lucene.search.Query;
  14. import org.apache.lucene.search.highlight.Highlighter;
  15. import org.apache.lucene.search.highlight.QueryScorer;
  16. import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
  17. public class ExtractDigest {
  18. private String indexPath = "H://index";
  19. private Analyzer analyzer;
  20. private IndexSearcher searcher;
  21. private String prefixHTML = "<font color='red'>";
  22. private String suffixHTML = "</font>";
  23. public ExtractDigest(){
  24.    analyzer = new ThesaurusAnalyzer();
  25. }
  26. public void createIndex() throws IOException {
  27.    IndexWriter writer = new IndexWriter(indexPath,analyzer,true);
  28.    Document docA = new Document();
  29.    String fileTextA = "挖掘频繁项集的方法可以扩展到挖掘闭频繁项集(由它们容易导出频繁项集的集合)。这些方法结合了附加的优化技术,如项合并、子项剪枝和项跳过,以及模式树中产生的项集的有效子集检查。挖掘频繁项集和关联已经用不同的方法扩展,包括挖掘多层关联规则和多维关联规则。多层关联规则可以根据每个抽象层的最小支持度阈值如何定义,使用多种策略挖掘。如一致的支持度、递减的支持度和基于分组的支持度。冗余的多层(后代)关联规则可以删除,如果根据其对应的祖先规则,他们的支持度和置信度接近于期望值的话。挖掘多维关联规则的技术可以根据对量化属性的处理分为若干类。第一,量化属性可以根据预定义的概念分层静态离散化。数据立方体非常适合这种方法,因为数据立方体和量化属性都可以利用概念分层。第二,可以挖掘量化关联规则,其中量化属性根据分箱和/或聚类动态离散化,“邻近的”关联规则可以用聚类合并,产生更简洁、更有意义的规则。基于约束的规则挖掘允许用户通过提供元规则(即模式模板)和其他挖掘约束对规则搜索聚焦。这种挖掘推动了说明性数据挖掘查询语言和用户界面的使用,并对挖掘查询优化提出了巨大挑战。规则约束可以分为五类:反单调的、单调的、简洁的、可转变的和不可转变的。前四类约束可以在频繁项集挖掘中使用,使挖掘更有功效,更有效率。没有进一步分析或领域知识,关联规则不应该直接用于预测。它们不必指示因果关系。然而,对于进一步探查,它们是有帮助的切入点,使得它们成为理解数据的流行工具。流数据不断地在计算机系统中流进流出并且具有变化的更新速度,涉及数据流的应用非常广泛。大纲提供数据流的汇总,通常用来返回查询的近似解答。随机抽样、滑动窗口、直方图、多分辨率方法、梗概以及随机算法都是大纲的形式。倾斜时间框架模型允许数据以多个时间粒度存储,最近的时间记录在最细的粒度上,最远的时间记录在最粗的粒度上。流立方体可以存储压缩的数据,对时间维度使用倾斜时间框架模型,并且仅在一些关键的层上存储数据,关键层反映了分析人员最感兴趣的数据层,从而基于到关键层的“常用路径”进行部分物化。";
  30.    Field fieldA = new Field("contents", fileTextA, Field.Store.YES,Field.Index.TOKENIZED);
  31.    docA.add(fieldA); 
  32.   
  33.    Document docB = new Document();
  34.    String fileTextB = " 数据挖掘(Data Mining),又称为数据库中的知识发现(Knowledge Discovery in Database, KDD),就是从大量数据中获取有效的、新颖的、潜在有用的、最终可理解的模式的非平凡过程,简单的说,数据挖掘就是从大量数据中提取或“挖掘”知识。";
  35.    Field fieldB = new Field("contents", fileTextB, Field.Store.YES,Field.Index.TOKENIZED);
  36.    docB.add(fieldB); 
  37.   
  38.    writer.addDocument(docA);
  39.    writer.addDocument(docB);
  40.    writer.optimize();
  41.    writer.close();
  42. }
  43. public void search(String fieldName,String keyword) throws CorruptIndexException, IOException, ParseException{
  44.    searcher = new IndexSearcher(indexPath); 
  45.    QueryParser queryParse = new QueryParser(fieldName, analyzer); 
  46.    Query query = queryParse.parse(keyword); 
  47.    Hits hits = searcher.search(query);
  48.    for(int i=0;i<hits.length();i++){
  49.     Document doc = hits.doc(i);
  50.    String text = doc.get(fieldName);
  51.    //System.out.println("||||||||||||"+text);
  52.     int htmlLength = prefixHTML.length()+suffixHTML.length();
  53.     System.out.println("高亮HTML的总长度为"+htmlLength); 
  54.     SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter(prefixHTML, suffixHTML);    
  55.             Highlighter highlighter = new Highlighter(simpleHTMLFormatter,new QueryScorer(query));    
  56.             String highLightText = highlighter.getBestFragment(analyzer,"contents",text);
  57.             System.out.println("★高亮显示第 "+(i+1) +" 条检索结果如下所示:"); 
  58.             System.out.println(highLightText); 
  59.             System.out.println("显示第 "+(i+1) +" 条检索结果摘要的长度为(含高亮HTML代码):"+highLightText.length()); 
  60.    }
  61.    searcher.close();
  62. }
  63. public static void main(String[] args) {
  64.    ExtractDigest ed = new ExtractDigest();
  65.    try {
  66.     ed.createIndex();
  67.     ed.search("contents""根据 挖掘");
  68.    } catch (CorruptIndexException e) {
  69.     e.printStackTrace();
  70.    } catch (IOException e) {
  71.     e.printStackTrace();
  72.    } catch (ParseException e) {
  73.     e.printStackTrace();
  74.    }
  75. }
  76. }

同时我们也可以使用另一种形式,但换汤不换药,本质上是一样的。

  1. public void search(String fieldName,String keyword) throws CorruptIndexException, IOException, ParseException{   // 检索的方法,并实现高亮显示
  2.    searcher = new IndexSearcher(indexPath); 
  3.    QueryParser queryParse = new QueryParser(fieldName, analyzer);     //   构造QueryParser,解析用户输入的检索关键字
  4.    Query query = queryParse.parse(keyword); 
  5.    Hits hits = searcher.search(query);
  6.    for(int i=0;i<hits.length();i++){
  7.     Document doc = hits.doc(i);
  8.     String text = doc.get(fieldName);
  9.     SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'>""</font>");    
  10.             Highlighter highlighter = new Highlighter(simpleHTMLFormatter,new QueryScorer(query));    
  11.             highlighter.setTextFragmenter(new SimpleFragmenter(text.length()));       
  12.             if (text != null) {    
  13.                 TokenStream tokenStream = analyzer.tokenStream(fieldName,new StringReader(text));    
  14.                 String highLightText = highlighter.getBestFragment(tokenStream, text); 
  15.                 System.out.println("★高亮显示第 "+(i+1) +" 条检索结果如下所示:"); 
  16.                 System.out.println(highLightText);    
  17.             } 
  18.    }
  19.    searcher.close();
  20. }

上面程序,检索“根据 挖掘”,首先使用QueryParser解析,提取Term为“根据”和“挖掘”,检索结果应该在提取的摘要中高亮显示这两个Term的text。

运行结果如下所示:

词库尚未被初始化,开始初始化词库.
初始化词库结束。用时:3985毫秒;
共添加195574个词语。
高亮HTML的总长度为25
★高亮显示第 1 条检索结果如下所示:
同的方法扩展,包括<font color='red'>挖掘</font>多层关联规则和多维关联规则。多层关联规则可以<font color='red'>根据</font>每个抽象层的最小支持度阈值如何定义,使用多种策略<font color='red'>挖掘</font>。如一致的支持度、递减的支持度和基于分组的支持度。冗余的多层(后代)关联规则
显示第 1 条检索结果摘要的长度为(含高亮HTML代码):174
高亮HTML的总长度为25
★高亮显示第 2 条检索结果如下所示:
数据<font color='red'>挖掘</font>(Data Mining),又称为数据库中的知识发现(Knowledge Discovery in Database, KDD),就是从大量数据中获取有效的、新颖的、潜在有用的、最终可理解
显示第 2 条检索结果摘要的长度为(含高亮HTML代码):124

上面程序中,在进行分析的时候,构造Field,同时对指定原始文本进行了存储,如下所示:

Field fieldA = new Field("contents", fileTextA, Field.Store.YES,Field.Index.TOKENIZED);

这个Field.Store.YES指定的存储,但是在实际中这样会浪费存储空间,而且造成索引管理的困难,所以在实际中是直接从数据库中查询出原始文件的文本内容,然后对这个文本进行处理,对其进行提取摘要的操作。也就是在上面String text = doc.get(fieldName);这一步,text的内容是根据Document的ID,从数据库中查询出来的,避免了IO操作,从而提高了检索速度,而且便利了索引文件的管理。

抱歉!评论已关闭.