【问题标题】:EnglishAnalyzer with better stop world filtering?具有更好的停止世界过滤的EnglishAnalyzer?
【发布时间】:2017-02-08 14:37:39
【问题描述】:

我正在使用 Apache Mahout 创建 TFIDF 向量。我将 EnglishAnalyzer 指定为文档标记的一部分,如下所示:

DocumentProcessor.tokenizeDocuments(documentsSequencePath, EnglishAnalyzer.class, tokenizedDocumentsPath, configuration); 

这为我称为business.txt 的文档提供了以下向量。我很惊讶在那里看到无用的词,例如haveonie.g.。我的其他文件之一加载更多。

对我来说,提高所找到字词质量的最简单方法是什么?我知道 EnglishAnalyzer 可以传递一个停用词列表,但构造函数是通过反射调用的,所以看起来我不能这样做。

我应该编写自己的分析器吗?我对如何编写标记器、过滤器等感到有点困惑。我可以重复使用 EnglishAnalyzer 和我自己的过滤器吗?以这种方式子类化 EnglishAnalyzer 似乎是不可能的。

# document: tfidf-score term
business.txt: 109 comput
business.txt: 110 us
business.txt: 111 innov
business.txt: 111 profit
business.txt: 112 market
business.txt: 114 technolog
business.txt: 117 revolut
business.txt: 119 on
business.txt: 119 platform
business.txt: 119 strategi
business.txt: 120 logo
business.txt: 121 i
business.txt: 121 pirat
business.txt: 123 econom
business.txt: 127 creation
business.txt: 127 have
business.txt: 128 peopl
business.txt: 128 compani
business.txt: 134 idea
business.txt: 139 luxuri
business.txt: 139 synergi
business.txt: 140 disrupt
business.txt: 140 your
business.txt: 141 piraci
business.txt: 145 product
business.txt: 147 busi
business.txt: 168 funnel
business.txt: 176 you
business.txt: 186 custom
business.txt: 197 e.g
business.txt: 301 brand

【问题讨论】:

    标签: lucene mahout tf-idf


    【解决方案1】:

    您可以将自定义停用词集传递给EnglishAnalyzer ctor。此停用词列表通常从文件中加载,该文件是每行一个停用词的纯文本。看起来像这样:

    String stopFileLocation = "\\path\\to\\my\\stopwords.txt"; 
    CharArraySet stopwords = StopwordAnalyzerBase.loadStopwordSet(
            Paths.get(StopFileLocation));
    EnglishAnalyzer analyzer = new EnglishAnalyzer(stopwords);
    

    我不明白你应该如何将 ctor 参数传递给你指定的 Mahout 方法。我真的不认识马豪。如果你不能,那么可以,你可以通过复制EnglishAnalyzer 创建一个自定义分析器,并在那里加载你自己的停用词。这是一个从文件加载自定义停用词列表的示例,并且没有词干排除(即,为简洁起见,删除了词干排除内容)。

    public final class EnglishAnalyzerCustomStops extends StopwordAnalyzerBase {
      private static String StopFileLocation = "\\path\\to\\my\\stopwords.txt"; 
    
      public EnglishAnalyzerCustomStops() throws IOException {
        super(StopwordAnalyzerBase.loadStopwordSet(Paths.get(StopFileLocation)));
      }
    
      protected TokenStreamComponents createComponents(String fieldName) {
        final Tokenizer source = new StandardTokenizer();
        TokenStream result = new StandardFilter(source);
        result = new EnglishPossessiveFilter(result);
        result = new LowerCaseFilter(result);
        result = new StopFilter(result, stopwords);
        result = new PorterStemFilter(result);
        return new TokenStreamComponents(source, result);
      }
    
      protected TokenStream normalize(String fieldName, TokenStream in) {
        TokenStream result = new StandardFilter(in);
        result = new LowerCaseFilter(result);
        return result;
      }
    }
    

    【讨论】:

    • 谢谢,我很感激在提供可以完成这项工作的代码方面的帮助。我有点惊讶,没有更聪明的方法可以在不复制和粘贴的情况下重用分析器。
    • @Sridhar-Sarnobat - 分析器的组装非常简单。您几乎只需要在createComponents 中实现分析链。相当肯定这就是为什么它们被标记为最终的原因。一般来说,扩展它们并没有多大意义,如果你正在实现自定义分析器,你真的应该查看正在应用的标记器和过滤器。
    • 好的,谢谢您的建议。我需要开始学习如何编写自己的分析器,以及它的每个组件实际上是做什么的。
    猜你喜欢
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多