如何使用Lucene获取频繁出现的短语

我想在Lucene中找到一些经常出现的短语。 我从TXT文件中获取了一些信息,并且因为没有短语信息而丢失了很多上下文,例如“信息检索”被索引为两个单独的单词。

获取这样的短语的方法是什么? 我在互联网上找不到任何有用的东西,所有的建议,链接,提示特别是例子表示赞赏!

编辑:我只是按标题和内容存储我的文件:

Document doc = new Document(); doc.add(new Field("name", f.getName(), Field.Store.YES, Field.Index.NOT_ANALYZED)); doc.add(new Field("text", fReader, Field.TermVector.WITH_POSITIONS_OFFSETS)); 

因为我正在做的事情,最重要的是文件的内容。 标题往往不具有描述性(例如,我有许多PDF学术论文,其标题是代码或数字)。

我迫切需要从文本内容中索引最常出现的短语,刚才我看到这个简单的“词袋”方法效率不高。

朱莉娅,你正在寻找的是n-gram ,特别是Bigrams (也称为搭配)。

这是一篇关于从Manning和Schutze的统计自然语言处理基础中 找到搭配(PDF)的章节 。

为了用Lucene做这个,我建议使用Solr和ShingleFilterFactory 。 有关详细信息,请参阅此讨论 。

您是否可以发布您编写的任何代码?

基本上很大程度上取决于您在lucene中创建字段和存储文档的方式。

让我们考虑一个我有两个字段的案例:ID和评论; 在我的ID字段中,我允许这样的值’查找nemo’即带空格的字符串。 而“评论”是一个自由流动的文本字段,即我允许我的键盘允许的任何内容和lucene可以理解的内容。

现在在现实生活中,将我的ID:’find nemo’作为两个不同的可搜索字符串是没有意义的。 而我想在评论中索引所有内容。

所以我要做的是,我将创建一个文件( org.apache.lucene.document.Document )对象来处理这个…这样的事情

 Document doc = new Document(); doc.add(new Field("comments","Finding nemo was a very tough job for a clown fish ...", Field.Store.YES, Field.Index.ANALYZED)); doc.add(new Field("id", "finding nemo", Field.Store.YES, Field.Index.NOT_ANALYZED)); 

所以,基本上我创建了两个字段:

  1. 评论:我更倾向于使用Field.Index.ANALYZED进行分析
  2. id:我指示lucene存储它但分析它Field.Index.NOT_ANALYZED

这是您为默认令牌器和分析器自定义lucene的方法。 否则,您可以编写自己的Tokenizer和分析器。

链接 http://darksleep.com/lucene/

希望对你有帮助… :)

那么丢失短语的上下文的问题可以通过使用PhraseQuery来解决。

默认情况下,索引包含术语的位置信息,只要您没有通过使用omitTermFreqAndPositions选项建立索引来创建纯布尔字段。 PhraseQuery使用此信息来查找术语在彼此的特定距离内的文档。

例如,假设一个字段包含短语“快速的棕色狐狸跳过懒狗”。 在不知道确切短语的情况下,您仍然可以通过搜索具有快速和狐狸彼此接近的字段的文档来查找此文档。 当然,一个普通的TermQuery可以找到知道这些单词的文档,但是在这种情况下我们只想要那些文字具有短语的文档,其中单词并排(快速狐狸)或者中间有一个单词(快速[无关]狐狸)。 要被视为匹配的术语之间的最大允许位置距离称为slop。 距离是按顺序重建短语的术语的位置移动次数。

查看Lucene的JavaDoc for PhraseQuery

请参阅此示例代码,该代码演示了如何使用各种查询对象:

您还可以尝试在BooleanQuery类的帮助下组合各种查询类型。

关于短语的频率,我认为Lucene的评分考虑了文档中出现的术语的频率。