【问题标题】:Find frequent phrases in text查找文本中的常用短语
【发布时间】:2015-07-30 14:44:33
【问题描述】:

有没有办法用Lucene 搜索常用短语?

我正在成功搜索常用词:

TermStats[] ts = HighFreqTerms.getHighFreqTerms(reader, 20, fieldName, comparator);

但这会带来单个单词,我正在寻找一种方法来搜索频繁的两个(或任意数量)单词组合。

为了澄清,我不是在寻找我知道的前两个词(例如 fast 和 car),而是前两个常用词组合。因此,如果我的文本是“这是一辆快车,这也是一辆快车”,我会得到“快车”和“这是”是前两个单词组合的结果。

我查看了here 的讨论,但它提供了solr 的解决方案,我正在寻找Lucene 的内容,无论如何相关链接已损坏。

编辑:按照 femtoRgon 的评论,这里有一些来自我的 Analyzer 的代码。这是应该添加ShingleFilter 的地方吗?它似乎不起作用,因为我的输出如下所示:

ed d 
d 
d   p
 p
 p pl  
pl
pl le

我需要的是输出包含成对的完整单词。

这是我的createComponents 方法:

@Override
protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
    Tokenizer source = new NGramTokenizer(Version.LUCENE_47, reader, 2, 2);     
    ShingleFilter sf = new ShingleFilter(source, 2, 2);

    TokenStreamComponents tsc = new TokenStreamComponents(source, sf);  
    return tsc;
}

EDIT2:我在 femtoRgon 的评论之后将NGramTokenizer 更改为StandardTokenizer,现在我得到了完整的单词,但我不需要单个单词,只需要成对的单词。

这是代码:

Tokenizer source = new StandardTokenizer(Version.LUCENE_47, reader);        
ShingleFilter sf = new ShingleFilter(source, 2, 2);

注意2, 2,根据文档应该生成最小字数为2,最大字数为2。但实际上它会生成这个输出:

and
and other
other
other airborne
airborne
airborne particles

那么我如何摆脱单个单词并得到这个输出呢?

and other
other airborne
airborne particles

【问题讨论】:

  • ShingleFilter 肯定还在,这也是我的第一个想法。
  • @femtoRgon 很酷,谢谢,我会试一试。但是,我该如何获得最频繁的呢?
  • HighFreqTerms 应该可以正常工作。您索引适当大小的带状疱疹,这会在索引中为您提供多字词,然后您只需检查高频词。
  • @femtoRgon 我编辑了问题以反映我使用 ShingleFilter 的尝试。它似乎不起作用,但也许我做得不对。
  • NGramTokenizer 不是与ShingleFilter 一起使用的好标记器。例如,您会想要使用可分隔成单词的东西,StandardTokenizer

标签: lucene


【解决方案1】:

这是我完成这项工作的完整 Analyzer 课程。请注意,TokenStreamComponents 方法是 ShingleFilter 在 femtoRgon 优秀 cmets 之后声明我的问题的地方。只需输入您自己的字符串,指定minWordsmaxWords 并运行它。

public class RMAnalyzer extends Analyzer {

    public static String someString = "some string";
    private int minWords = 2;
    private int maxWords = 2;


    public static void main(String[] args) {
        RMAnalyzer rma = new RMAnalyzer(2, 2);
        rma.findFrequentTerms();
        rma.close();
    }


    public RMAnalyzer(int minWords, int maxWords) { 
        this.minWords = minWords;
        this.maxWords = maxWords;
    }

    public void findFrequentTerms() {
        StringReader sr = new StringReader(someString);
        try {
            TokenStream tokenStream = tokenStream("title", sr);
            OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);
            CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
            tokenStream.reset();

            while (tokenStream.incrementToken()) {
                String term = charTermAttribute.toString();
                System.out.println(term);
            }                       
        } catch(Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
        Tokenizer source = new StandardTokenizer(Version.LUCENE_47, reader);        
        ShingleFilter sf = new ShingleFilter(source, minWords, maxWords);
        sf.setOutputUnigrams(false); // makes it so no one word phrases out in the output.
        sf.setOutputUnigramsIfNoShingles(true); // if not enough for min, show anyway.

        TokenStreamComponents tsc = new TokenStreamComponents(source, sf);  
        return tsc;
    }
}

【讨论】:

    猜你喜欢
    • 2014-06-07
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 2010-12-28
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多