2015-07-30 4 views
0

Есть ли способ поиска частых фраз с Lucene?Найти частые фразы в тексте

Я успешно поиске частых слов:

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

, но это приносит отдельные слова, и я ищу способ для поиска частых два (или любое количество) словосочетаниям.

Чтобы уточнить, я не ищу два первых слова, которые я знаю (например, быстро и автомобиль), но верхние две частые комбинации слов. Поэтому, если мой текст «это быстрый автомобиль, и это тоже быстрый автомобиль», я получу в результате, что «быстрая машина» и «это» являются двумя верхними комбинациями слов.

Я смотрел на обсуждение here но предлагает решение с solr и я искал что-то с Lucene, и в любом случае соответствующая ссылка сломана.

EDIT: комментарий пользователя 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: Я изменил NGramTokenizer на StandardTokenizer следующий комментарий femtoRgon и теперь я получаю полные слова, но я не нужны отдельные слова, только пары.

Это код:

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 
+0

[ShingleFilter] (https://lucene.apache.org/core/5_2_1/analyzers-common/org/apache/lucene/analysis/shingle/ShingleFilter.html), безусловно, все еще вокруг, и это моя первая мысль, также. – femtoRgon

+0

@femtoRgon классно, спасибо, я попробую. Но как мне тогда заняться самыми частыми? – Eddy

+0

'HighFreqTerms' должен работать нормально. Вы индексируете черепицу соответствующих размеров, что дает вам многословные термины в индексе, тогда вы просто проверяете высокочастотные. – femtoRgon

ответ

0

Это мой полный класс Analyzer, который выполняет эту работу. Обратите внимание, что метод TokenStreamComponents - это то, где ShingleFilter объявлен после замечательных замечаний к моему вопросу. Просто введите свою строку, укажите minWords и maxWords и запустите ее.

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; 
    } 
} 
Смежные вопросы