用Lucene实现英语词干提取

n6lpvg4x  于 2022-11-07  发布在  Lucene
关注(0)|答案(7)|浏览(196)

我在一个Java应用程序中处理一些英语文本,我需要对它们进行词干处理。例如,从文本“compliances/amenity”中,我需要得到“amenit”。
该函数如下所示:

String stemTerm(String term){
   ...
}

我找到了Lucene分析器,但它看起来太复杂了,不适合我的需要。http://lucene.apache.org/java/2_2_0/api/org/apache/lucene/analysis/PorterStemFilter.html
有没有一种方法可以用它来词干的话,而不建立一个分析器?我不明白所有的分析器业务...

  • EDIT*:我实际上需要一个词干+词素化。Lucene能做到吗?
nhhxz33t

nhhxz33t1#

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

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

希望这个能帮上忙!

n9vozmp4

n9vozmp42#

import org.apache.lucene.analysis.PorterStemmer;
...
String stemTerm (String term) {
    PorterStemmer stemmer = new PorterStemmer();
    return stemmer.stem(term);
}

如果你只想做词干分析,那么你应该使用this而不是Lucene。

**编辑:**在将term传递给stem()之前,应将其小写.

vmpqdwk3

vmpqdwk33#

你为什么不用“英语分析器”呢?它使用起来很简单,而且我认为它能解决你的问题:

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

希望对你有帮助!

z9smfwbn

z9smfwbn4#

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

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不能作为类(隐藏)使用,因此您不能直接使用它。
希望这对你有帮助。

lsmd5eda

lsmd5eda5#

下面是如何在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());
}
eivgtgni

eivgtgni6#

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

isr3a4wc

isr3a4wc7#

由于PorterStemmer不是公共的,所以我们不能调用PorterStemmer的stem函数。
相反,我们可以使用KStemmer/KStemFilter将单词词干提取到其词根。
下面是scala代码片段,它接受字符串并转换为词干化字符串。
导入源代码,分析源代码,分析源代码,分析源代码
导入java.io.StringReader
对象词干生成器{ def stem(输入:字符串):字符串={

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

}
}

相关问题