29

我在 Java 应用程序中处理一些英文文本,我需要对它们进行词干处理。例如,从文本“amenities/amenity”中,我需要得到“amenit”。

该函数如下所示:

String stemTerm(String term){
   ...
}

我找到了 Lucene Analyzer,但对于我需要的东西来说,它看起来太复杂了。 http://lucene.apache.org/java/2_2_0/api/org/apache/lucene/analysis/PorterStemFilter.html

有没有办法在不构建分析器的情况下使用它来阻止单词?我不了解所有分析仪业务...

编辑:我实际上需要一个词干+词形还原。Lucene 可以做到这一点吗?

4

7 回答 7

27

SnowballAnalyzer 已弃用,您可以改用 Lucene Porter Stemmer:

 PorterStemmer stem = new PorterStemmer();
 stem.setCurrent(word);
 stem.stem();
 String result = stem.getCurrent();

希望这有帮助!

于 2012-11-04T12:26:49.360 回答
23
import org.apache.lucene.analysis.PorterStemmer;
...
String stemTerm (String term) {
    PorterStemmer stemmer = new PorterStemmer();
    return stemmer.stem(term);
}

有关更多详细信息,请参见此处。如果您只想使用词干提取,那么您应该使用而不是 Lucene。

编辑:在将term其传递给stem().

于 2011-03-22T16:44:04.263 回答
6

你为什么不使用“EnglishAnalyzer”?使用它很简单,我认为它可以解决您的问题:

EnglishAnalyzer en_an = new EnglishAnalyzer(Version.LUCENE_34);
QueryParser parser = new QueryParser(Version.LUCENE_34, "your_field", en_an);
String str = "amenities";
System.out.println("result: " + parser.parse(str)); //amenit

希望对你有帮助!

于 2011-11-24T06:47:18.580 回答
5

前面的示例将词干应用于搜索查询,因此如果您对全文词干感兴趣,可以尝试以下操作:

import java.io.*;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.tokenattributes.*;
import org.apache.lucene.analysis.snowball.*;
import org.apache.lucene.util.*;
...
public class Stemmer{
    public static String Stem(String text, String language){
        StringBuffer result = new StringBuffer();
        if (text!=null && text.trim().length()>0){
            StringReader tReader = new StringReader(text);
            Analyzer analyzer = new SnowballAnalyzer(Version.LUCENE_35,language);
            TokenStream tStream = analyzer.tokenStream("contents", tReader);
            TermAttribute term = tStream.addAttribute(TermAttribute.class);

            try {
                while (tStream.incrementToken()){
                    result.append(term.term());
                    result.append(" ");
                }
            } catch (IOException ioe){
                System.out.println("Error: "+ioe.getMessage());
            }
        }

        // If, for some reason, the stemming did not happen, return the original text
        if (result.length()==0)
            result.append(text);
        return result.toString().trim();
    }

    public static void main (String[] args){
        Stemmer.Stem("Michele Bachmann amenities pressed her allegations that the former head of her Iowa presidential bid was bribed by the campaign of rival Ron Paul to endorse him, even as one of her own aides denied the charge.", "English");
    }
}

TermAttribute 类已被弃用,Lucene 4 将不再支持,但文档并不清楚在其位置使用什么。

同样在第一个示例中,PorterStemmer 不能作为类(隐藏)使用,因此您不能直接使用它。

希望这可以帮助。

于 2011-12-30T16:37:30.907 回答
3

以下是在 JAVA 中使用 Snowball Stemmer 的方法:

import org.tartarus.snowball.ext.EnglishStemmer;

EnglishStemmer english = new EnglishStemmer();
String[] words = tokenizer("bank banker banking");
for(int i = 0; i < words.length; i++){
        english.setCurrent(words[i]);
        english.stem();
        System.out.println(english.getCurrent());
}
于 2014-08-13T18:53:12.713 回答
0

Ling pipe提供了许多分词器。它们可用于词干提取和停用词删除。它是一种简单而有效的词干提取方法。

于 2012-02-28T11:12:34.557 回答
0

由于 PorterStemmer 不是公开的,我们不能调用 PorterStemmer 的 stem 函数。

相反,我们可以使用 KStemmer/KStemFilter 将词提取到其词根。

下面是接受字符串并转换为词干字符串的 scala 代码片段

导入 org.apache.lucene.analysis.core.WhitespaceTokenizer 导入 o​​rg.apache.lucene.analysis.en.KStemFilter

导入 java.io.StringReader

object Stemmer { def stem(input:String):String={

val stemmed_string = new StringBuilder()

val inputReader = new StringReader(input.toLowerCase)

val whitespaceTokenizer = new WhitespaceTokenizer()
whitespaceTokenizer.setReader(inputReader)

val kStemmedTokenStream = new KStemFilter(whitespaceTokenizer)
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute

val charTermAttribute = kStemmedTokenStream.addAttribute(classOf[CharTermAttribute])

kStemmedTokenStream.reset
while (kStemmedTokenStream.incrementToken) {
  val term = charTermAttribute.toString
  stemmed_string.append(term+" ")
}
stemmed_string.toString().trim.toUpperCase

}

}

于 2021-05-26T05:03:32.607 回答