【问题标题】:Apache Lucene doesn't filter stop words despite the usage of StopAnalyzer and StopFilter尽管使用了 StopAnalyzer 和 StopFilter,Apache Lucene 不过滤停用词
【发布时间】:2016-07-14 10:56:08
【问题描述】:

我有一个基于 Apache Lucene 5.5 / 6.0 的模块,用于检索关键字。一切都很好,除了一件事——Lucene 不会过滤停用词。

我尝试使用两种不同的方法启用停用词过滤。

方法 #1:

tokenStream = new StopFilter(new ASCIIFoldingFilter(new ClassicFilter(new LowerCaseFilter(stdToken))), EnglishAnalyzer.getDefaultStopSet());
tokenStream.reset();

方法 #2:

tokenStream = new StopFilter(new ClassicFilter(new LowerCaseFilter(stdToken)), StopAnalyzer.ENGLISH_STOP_WORDS_SET);
tokenStream.reset();

完整代码在这里:
https://stackoverflow.com/a/36237769/462347

我的问题:

  1. 为什么 Lucene 不过滤停用词?
  2. 如何在 Lucene 5.5 / 6.0 中启用停用词过滤?

【问题讨论】:

    标签: java apache lucene information-retrieval stop-words


    【解决方案1】:

    刚刚测试了方法 1 和方法 2,它们似乎都可以很好地过滤掉停用词。这是我的测试方法:

    public static void main(String[] args) throws IOException, ParseException, org.apache.lucene.queryparser.surround.parser.ParseException 
    {
         StandardTokenizer stdToken = new StandardTokenizer();
         stdToken.setReader(new StringReader("Some stuff that is in need of analysis"));
         TokenStream tokenStream;
    
         //You're code starts here
         tokenStream = new StopFilter(new ASCIIFoldingFilter(new ClassicFilter(new LowerCaseFilter(stdToken))), EnglishAnalyzer.getDefaultStopSet());
         tokenStream.reset();
         //And ends here
    
         CharTermAttribute token = tokenStream.getAttribute(CharTermAttribute.class);
         while (tokenStream.incrementToken()) {
             System.out.println(token.toString());
         }
         tokenStream.close();
    }
    

    结果:

    一些
    东西
    需要
    分析

    这消除了我示例中的四个停用词。

    【讨论】:

    • 问题是Lucene没有过滤掉weI等常用英文单词。我应该附上其他扩展停用词词典吗? Lucene 是否提供其他停用词词典?
    • EnglishAnalyzerStandardAnalyzer 使用相同的停用词集,所以我不相信 lucene 中包含更广泛的停用词列表。所以,是的,您可能需要创建自己的。如果您使用的是 StandardAnalyzer,则可以轻松地将停用词存储在纯文本文件中,并将阅读器传递给构造函数。
    • 您是指StandardAnalyzer 还是StandardTokenizer?我使用StandardAnalyzer.STOP_WORDS_SET,但没有使用StandardAnalyzer 的构造函数。相比之下,我有stdToken.setReader(new StringReader(fullText));。我应该把停用词列表放在哪里?
    • 您需要将停用词的CharArraySet 传递给您的StopFilterStandardAnalyzer 只是有一个方便的 ctor。要从文件构建,您需要使用WordListLoader.getWordSet。或者您可以自己创建CharArraySet,使用起来非常简单,真的。
    • 太好了,特别感谢WordlistLoader.getWordSet
    【解决方案2】:

    陷阱在默认的 Lucene 的停用词列表中,我预计,它更广泛。

    这是默认情况下尝试加载自定义停用词列表的代码,如果失败则使用标准的:

    CharArraySet stopWordsSet;
    
    try {
        // use customized stop words list
        String stopWordsDictionary = FileUtils.readFileToString(new File(%PATH_TO_FILE%));
        stopWordsSet = WordlistLoader.getWordSet(new StringReader(stopWordsDictionary));
    } catch (FileNotFoundException e) {
        // use standard stop words list
        stopWordsSet = CharArraySet.copy(StandardAnalyzer.STOP_WORDS_SET);
    }
    
    tokenStream = new StopFilter(new ASCIIFoldingFilter(new ClassicFilter(new LowerCaseFilter(stdToken))), stopWordsSet);
    tokenStream.reset();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-05
      • 2016-06-08
      相关资源
      最近更新 更多