2009-10-16 15 views
20

Sto cercando un'implementazione lemmatisation per l'inglese in Java. Ne ho già trovati alcuni, ma ho bisogno di qualcosa che non abbia bisogno di molta memoria per funzionare (1 GB in alto). Grazie. Non ho bisogno di uno stelo.Lemmatization java

+0

Avete bisogno vero lemmatizzazione (di solito richiede un elenco di parole di dimensioni decenti) o è un discreto tipo Porter, Snowball o Paice-Husk abbastanza buono? – erickson

+0

@erickson - Conosci una vera lemmatizzazione (elenco di parole)? Ne ho bisogno se ce n'è. –

+0

@JohnS - La migliore lista di parole inglese che ho trovato è quella sviluppata dai giocatori del gioco di parole Scrabble, OWL2. Sfortunatamente, non è "aperto". Questo, insieme a qualcosa come WordNet, potrebbe servire come base per un buon lemmatizzatore. Ma non conosco nessuno che lo abbia fatto. – erickson

risposta

-1

C'è un JNI per hunspell, che è il correttore utilizzato in ufficio aperto e FireFox. http://hunspell.sourceforge.net/

+1

È un correttore ortografico, non un lemmatizzatore. –

+2

Non è solo un correttore ortografico, è possibile utilizzarlo per la lemmatizzazione. Nella nuova versione di Lucene possiamo anche trovare un filtro Hunspell. –

33

La libreria Stanford CoreNLP Java contiene un lemmatizer che è un po 'alta intensità di risorse, ma ho incontrato sul mio computer portatile con < 512MB di RAM.

usarlo:

  1. Download the jar files;
  2. Creare un nuovo progetto nel proprio editor di scelta/creare uno script ant che includa tutti i file jar contenuti nell'archivio appena scaricato;
  3. Creare un nuovo Java come mostrato di seguito (basato sul frammento dal sito di Stanford); risposta
import java.util.Properties; 

public class StanfordLemmatizer { 

    protected StanfordCoreNLP pipeline; 

    public StanfordLemmatizer() { 
     // Create StanfordCoreNLP object properties, with POS tagging 
     // (required for lemmatization), and lemmatization 
     Properties props; 
     props = new Properties(); 
     props.put("annotators", "tokenize, ssplit, pos, lemma"); 

     // StanfordCoreNLP loads a lot of models, so you probably 
     // only want to do this once per execution 
     this.pipeline = new StanfordCoreNLP(props); 
    } 

    public List<String> lemmatize(String documentText) 
    { 
     List<String> lemmas = new LinkedList<String>(); 

     // create an empty Annotation just with the given text 
     Annotation document = new Annotation(documentText); 

     // run all Annotators on this text 
     this.pipeline.annotate(document); 

     // Iterate over all of the sentences found 
     List<CoreMap> sentences = document.get(SentencesAnnotation.class); 
     for(CoreMap sentence: sentences) { 
      // Iterate over all tokens in a sentence 
      for (CoreLabel token: sentence.get(TokensAnnotation.class)) { 
       // Retrieve and add the lemma for each word into the list of lemmas 
       lemmas.add(token.get(LemmaAnnotation.class)); 
      } 
     } 

     return lemmas; 
    } 
} 
+1

c'è un tutorial? la documentazione sembra piuttosto confusa! – CTsiddharth

+0

Ricevo questa eccezione quando eseguo questo codice: Eccezione nel thread "main" java.lang.NoSuchMethodError: edu.stanford.nlp.util.Generics.newHashMap() Ljava/util/Map; \t a edu.stanford.nlp.pipeline.AnnotatorPool. (AnnotatorPool.java:27) \t a edu.stanford.nlp.pipeline.StanfordCoreNLP.getDefaultAnnotatorPool (StanfordCoreNLP.java:306) \t a edu.stanford.nlp.pipeline.StanfordCoreNLP.construct (StanfordCoreNLP.java:250) \t a edu.stanford.nlp.pipeline.StanfordCoreNLP. (StanfordCoreNLP.java:127) \t a edu.stanford.nlp.pipeline.StanfordCoreNLP. (StanfordCoreNLP.java:123) ..... Qualche idea? – user1028408

+0

Il javadoc è qui http://www-nlp.stanford.edu/nlp/javadoc/javanlp/edu/stanford/nlp/process/Morphology.html e questo esempio di codice è più facile da capire - http: //sw.deri .org/2008/11/match/aroma/src/utils/StanfordPOSTagger.java Basta usare il metodo di istanza Morphology # lemma – ruhong

14

di Chris in merito alla Standford Lemmatizer è grande! Assolutamente bella. Ha persino incluso un puntatore ai file jar, quindi non ho dovuto cercarlo su google.

Ma una delle sue linee di codice avuto un errore di sintassi (in qualche modo commutato le finali parentesi di chiusura e virgola nella riga che inizia con "lemmas.add ...), e si è dimenticato di includere le importazioni.

Per quanto riguarda l'errore NoSuchMethodError, di solito è causato dal fatto che il metodo non viene reso statico pubblico, ma se si guarda il codice stesso (a http://grepcode.com/file/repo1.maven.org/maven2/com.guokr/stan-cn-nlp/0.0.2/edu/stanford/nlp/util/Generics.java?av=h) questo non è il problema. Sospetto che il problema sia da qualche parte nel percorso di compilazione (Sto usando Eclipse Kepler, quindi non è stato un problema configurare i 33 file jar che uso nel mio progetto)

Di seguito è riportata la mia correzione minore del codice di Chris, insieme ad un esempio (il mio ap ologie a Evanescence per macellare i loro testi perfetti):

import java.util.LinkedList; 
import java.util.List; 
import java.util.Properties; 

import edu.stanford.nlp.ling.CoreAnnotations.LemmaAnnotation; 
import edu.stanford.nlp.ling.CoreAnnotations.SentencesAnnotation; 
import edu.stanford.nlp.ling.CoreAnnotations.TokensAnnotation; 
import edu.stanford.nlp.ling.CoreLabel; 
import edu.stanford.nlp.pipeline.Annotation; 
import edu.stanford.nlp.pipeline.StanfordCoreNLP; 
import edu.stanford.nlp.util.CoreMap; 

public class StanfordLemmatizer { 

    protected StanfordCoreNLP pipeline; 

    public StanfordLemmatizer() { 
     // Create StanfordCoreNLP object properties, with POS tagging 
     // (required for lemmatization), and lemmatization 
     Properties props; 
     props = new Properties(); 
     props.put("annotators", "tokenize, ssplit, pos, lemma"); 

     /* 
     * This is a pipeline that takes in a string and returns various analyzed linguistic forms. 
     * The String is tokenized via a tokenizer (such as PTBTokenizerAnnotator), 
     * and then other sequence model style annotation can be used to add things like lemmas, 
     * POS tags, and named entities. These are returned as a list of CoreLabels. 
     * Other analysis components build and store parse trees, dependency graphs, etc. 
     * 
     * This class is designed to apply multiple Annotators to an Annotation. 
     * The idea is that you first build up the pipeline by adding Annotators, 
     * and then you take the objects you wish to annotate and pass them in and 
     * get in return a fully annotated object. 
     * 
     * StanfordCoreNLP loads a lot of models, so you probably 
     * only want to do this once per execution 
     */ 
     this.pipeline = new StanfordCoreNLP(props); 
    } 

    public List<String> lemmatize(String documentText) 
    { 
     List<String> lemmas = new LinkedList<String>(); 
     // Create an empty Annotation just with the given text 
     Annotation document = new Annotation(documentText); 
     // run all Annotators on this text 
     this.pipeline.annotate(document); 
     // Iterate over all of the sentences found 
     List<CoreMap> sentences = document.get(SentencesAnnotation.class); 
     for(CoreMap sentence: sentences) { 
      // Iterate over all tokens in a sentence 
      for (CoreLabel token: sentence.get(TokensAnnotation.class)) { 
       // Retrieve and add the lemma for each word into the 
       // list of lemmas 
       lemmas.add(token.get(LemmaAnnotation.class)); 
      } 
     } 
     return lemmas; 
    } 


    public static void main(String[] args) { 
     System.out.println("Starting Stanford Lemmatizer"); 
     String text = "How could you be seeing into my eyes like open doors? \n"+ 
       "You led me down into my core where I've became so numb \n"+ 
       "Without a soul my spirit's sleeping somewhere cold \n"+ 
       "Until you find it there and led it back home \n"+ 
       "You woke me up inside \n"+ 
       "Called my name and saved me from the dark \n"+ 
       "You have bidden my blood and it ran \n"+ 
       "Before I would become undone \n"+ 
       "You saved me from the nothing I've almost become \n"+ 
       "You were bringing me to life \n"+ 
       "Now that I knew what I'm without \n"+ 
       "You can've just left me \n"+ 
       "You breathed into me and made me real \n"+ 
       "Frozen inside without your touch \n"+ 
       "Without your love, darling \n"+ 
       "Only you are the life among the dead \n"+ 
       "I've been living a lie, there's nothing inside \n"+ 
       "You were bringing me to life."; 
     StanfordLemmatizer slem = new StanfordLemmatizer(); 
     System.out.println(slem.lemmatize(text)); 
    } 

} 

Ecco i miei risultati (sono rimasto molto colpito; ha catturato "'s" come "è" (a volte), e ha fatto quasi tutto il resto perfettamente):

partire Stanford Lemmatizer

Aggiunta commentatore tokenize

Aggiunta commentatore ssplit

Aggiunta annotator pos

Lettura del modello di tagger POS da edu/stanford/nlp/models/pos-tagger/english-left3words/english-left3words-distsim.tagger ... done [1.7 sec].

Aggiunta commentatore lemma

[come, potrebbe, voi, essere, vedere, nel, mio, occhio, come, aperto, porta,?tu, piombo, io, giù, dentro, mio, nucleo, dove, io, ho, divento, così, intorpidito, senza, a, anima, mio, spirito, 's, sonno, da qualche parte, freddo, finché, tu, trova, è, là, e, guida, torna indietro, a casa, tu, sveglia, io, su, dentro, chiama, mio, nome, e, salva, io, da, il, oscuro, tu, hai, offerta, mio, sangue, e, corri, prima, io, vorrei, diventare, disfare, tu, salvezza, io, da, il, niente, io, avere, quasi, diventare, tu, essere, portare, io, a, vita, ora, che, io, so, cosa, io, essere, senza, tu, posso, avere, solo, lasciare, io, tu, respirare, dentro, io, e, creare, io, reale, congelato, dentro, senza, tu, tocca, senza, tu, amore, ... tesoro, solo, tu, sii, la, vita, tra, il, morto, io, ho, essere, vivere, a, mentire, ,, ecco, essere, niente, dentro, è, sarà, portare, io, per la vita,]

+1

In qualsiasi modo posso sbarazzarmi dei messaggi "Aggiunta"? – Michael

+0

[Come funziona per una singola parola] (http://stackoverflow.com/questions/34963203/stanford-nlp-how-to-lemmatize-single-word)? – displayname

0

È possibile provare la Lemmatizer API gratuitamente qui:. http://twinword.com/lemmatizer.php

Scorrere verso il basso per trovare il punto finale Lemmatizer.

Ciò consentirà di portare "cani" a "cane", "abilità" a "abilità".

Se si passa in un POST o GET parametro chiamato "testo" con una stringa come "piante camminato":

// These code snippets use an open-source library. http://unirest.io/java 
HttpResponse<JsonNode> response = Unirest.post("[ENDPOINT URL]") 
.header("X-Mashape-Key", "[API KEY]") 
.header("Content-Type", "application/x-www-form-urlencoded") 
.header("Accept", "application/json") 
.field("text", "walked plants") 
.asJson(); 

si ottiene una risposta come questa:

{ 
    "lemma": { 
    "plant": 1, 
    "walk": 1 
    }, 
    "result_code": "200", 
    "result_msg": "Success" 
} 
+0

Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il link per riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. –

+0

Grazie per il suggerimento. Ho incluso la documentazione su come usarlo. –