用Lucene扼杀英语单词

时间:2011-03-22 13:14:56

标签: java lucene stemming porter-stemmer

我正在Java应用程序中处理一些英文文本,我需要阻止它们。 例如,从文字“amenities / amenity”我需要得到“amenit”。

该功能如下:

String stemTerm(String term){
   ...
}

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

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

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

7 个答案:

答案 0 :(得分:22)

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

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

希望这有帮助!

答案 1 :(得分:20)

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

有关详细信息,请参阅here。如果您想要完成阻止,那么您应该使用this而不是Lucene。

修改:在将term传递给stem()之前,您应小写{{1}}。

答案 2 :(得分: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

希望它可以帮到你!

答案 3 :(得分: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不能作为类(隐藏)使用,因此您无法直接使用它。

希望这有帮助。

答案 4 :(得分: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());
}

答案 5 :(得分:0)

Ling pipe提供了许多标记符。它们可用于阻止和停止删除单词。它是一种简单而有效的堵塞手段。

答案 6 :(得分:0)

由于 PorterStemmer 不是公开的,所以我们不能调用 PorterStemmer 的词干函数。

相反,我们可以使用 KStemmer/KStemFilter 将词干化为其根词。

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

导入 org.apache.lucene.analysis.core.WhitespaceTokenizer 导入 org.apache.lucene.analysis.en.KStemFilter

导入 java.io.StringReader

对象词干{ def 词干(输入:字符串):字符串={

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

}

}