我想在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学术论文,其标题是代码或数字)。
我迫切需要从文本内容中索引最常出现的短语,刚才我看到这个简单的“词袋”方法效率不高。
答案 0 :(得分:7)
朱莉娅,你正在寻找的是n-grams,特别是Bigrams(也称为搭配)。
这是来自Manning和Schutze的chapter about finding collocations (PDF)的Foundations of Statistical Natural Language Processing。
为了使用Lucene执行此操作,我建议将Solr与ShingleFilterFactory一起使用。 有关详细信息,请参阅this discussion。
答案 1 :(得分:0)
您是否可以发布您编写的任何代码?
基本上很大程度上取决于你在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));
所以,基本上我创建了两个字段:
Field.Index.ANALYZED
Field.Index.NOT_ANALYZED
这是为默认令牌器和分析器自定义lucene的方法。否则,您可以编写自己的Tokenizer和分析器。
链接(S)强> http://darksleep.com/lucene/
希望这会对你有所帮助...... :)
答案 2 :(得分:0)
使用PhraseQuery可以解决丢失短语上下文的问题。
默认情况下,索引包含术语的位置信息,只要您没有创建纯布尔值 通过使用omitTermFreqAndPositions选项建立索引的字段。 PhraseQuery使用此信息来查找术语彼此相距一定距离的文档。
例如,假设一个字段包含短语“快速棕色狐狸跳过懒狗”。如果不知道确切的短语,您仍然可以通过搜索具有快速和狐狸彼此接近的字段的文档来查找此文档。当然,一个简单的TermQuery可以找到知道这些单词的文档,但在这种情况下,我们只需要包含短语的文档,其中单词并排(快速狐狸)或者中间有一个单词(快速[无关]狐狸)。 要被视为匹配的术语之间的最大允许位置距离称为slop。 距离是按顺序重建短语的术语的位置移动次数。
查看Lucene's JavaDoc for PhraseQuery
See this example code which demonstrates how to work with various Query Objects:
您还可以尝试在BooleanQuery类的帮助下组合各种查询类型。
关于短语的频率,我认为Lucene的评分考虑了文档中出现的术语的频率。