2011-03-22 14 views
24

Estoy procesando algunos textos en inglés en una aplicación Java, y necesito detenerlos. Por ejemplo, del texto "comodidades/comodidades" necesito obtener "amenit".Stemming palabras en inglés con Lucene

La función se parece a:

String stemTerm(String term){ 
    ... 
} 

he encontrado el Analizador de Lucene, pero parece demasiado complicado para lo que necesito. http://lucene.apache.org/java/2_2_0/api/org/apache/lucene/analysis/PorterStemFilter.html

¿Hay alguna manera de usarlo para contener palabras sin construir un Analizador? No entiendo todo el negocio del analizador ...

EDIT: realmente necesito una lematización + lematización. ¿Puede Lucene hacer esto?

+5

¿Por qué necesita para detener las palabras usted mismo? Lucene tiene un analizador llamado SnowballAnalyzer que usted acaba de crear una instancia con el nombre del tallo, p. 'nuevo SnowballAnalyzer (" Inglés ");'. – Thomas

+0

Implementación del algoritmo Knuth-Pratt http://www.fmi.uni-sofia.bg/fmi/logic/vboutchkova/sources/KMPMatch_java.html –

Respuesta

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

Ver here para obtener más detalles. Si la derivación es todo lo que desea hacer, entonces debe usar this en lugar de Lucene.

Editar: Debe minúsculas term antes de pasarla a stem().

+1

¿Es posible combinar el filtro de palabras de parada con el tallo? – Mulone

+0

¿Desea filtrar palabras de suspensión de una cadena con varias palabras o ya ha tokenizado (separado) las palabras y desea verificar una sola palabra? Si es solo un término como el anterior, simplemente crea un 'conjunto 'de todas las palabras de finalización y haz un' .contains() '. – nikhil500

+1

A partir de la versión actual de Lucene (3.5), PorterStemmer, aunque existe, no es público. No estoy seguro de quién/qué lo usa, pero no podemos. –

6

¿Por qué no utiliza el "EnglishAnalyzer"? Es fácil de usar y creo que resolvería su problema:

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 

Espero que te ayude!

+2

¿Qué está haciendo "your_field"? La documentación dice un críptico "el campo predeterminado para los términos de consulta". –

+0

Eso lo reduce a las palabras, pero no se detiene. Por lo menos no para mí. –

+0

Hace un tallo muy básico. No se necesita comenzar y cambiarlo para comenzar. – Whitecat

5

El ejemplo anterior se aplica derivada a una consulta de búsqueda, por lo que si usted es interesante para contener un texto completo usted puede intentar lo siguiente:

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"); 
    } 
} 

La clase TermAttribute ha quedado obsoleto y no dejará de ser apoyado en Lucene 4, pero la documentación no es clara sobre qué usar en su lugar.

También en el primer ejemplo, PorterStemmer no está disponible como clase (oculto) por lo que no puede usarlo directamente.

Espero que esto ayude.

+0

La respuesta de Giancarlo es correcta con un cambio menor de TermAttribute en CharTermAttribute ya que TermAttribute está en desuso. – amas

0

Ling pipe proporciona una cantidad de tokenizadores. Se pueden usar para detener y detener la eliminación de palabras. Es un medio simple y efectivo para frenar.

19

SnowballAnalyzer está en desuso, puede utilizar Lucene Porter Stemmer lugar:

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

Esperanza esta ayuda!

+2

PorterStemmer ya no es público (estúpidamente) - vea también http://stackoverflow.com/questions/15422485/lucene-porter-stemmer-not-public – 8bitjunkie

3

Aquí es cómo se puede utilizar la bola de nieve Stemmer en JAVA:

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()); 
} 
Cuestiones relacionadas