spanish lemmatizer and nlp stemming lemmatization

lemmatizer - stemming nlp



¿Cómo hago la palabra Stemming o Lemmatization? (19)

He probado PorterStemmer y Snowball, pero ninguno de los dos funciona en todas las palabras, faltan algunos muy comunes.

Mis palabras de prueba son: " gatos corriendo ranas cactus cactus comunidades de comunidades de cactus ", y ambos tienen menos de la mitad de la razón.

Ver también:


.Net lucene tiene una lectora porter incorporada. Puedes intentar eso. Pero tenga en cuenta que la derivación del portero no tiene en cuenta el contexto de la palabra al derivar el lema. (Repase el algoritmo y su implementación y verá cómo funciona)


Basado en varias respuestas en y blogs que he encontrado, este es el método que estoy usando, y parece devolver palabras reales bastante bien. La idea es dividir el texto entrante en una matriz de palabras (use el método que desee), y luego encuentre las partes del discurso (POS) para esas palabras y utilícelas para ayudar a detener y lematizar las palabras.

Su muestra anterior no funciona demasiado bien, porque el POS no puede determinarse. Sin embargo, si usamos una oración real, las cosas funcionan mucho mejor.

import nltk from nltk.corpus import wordnet lmtzr = nltk.WordNetLemmatizer().lemmatize def get_wordnet_pos(treebank_tag): if treebank_tag.startswith(''J''): return wordnet.ADJ elif treebank_tag.startswith(''V''): return wordnet.VERB elif treebank_tag.startswith(''N''): return wordnet.NOUN elif treebank_tag.startswith(''R''): return wordnet.ADV else: return wordnet.NOUN def normalize_text(text): word_pos = nltk.pos_tag(nltk.word_tokenize(text)) lemm_words = [lmtzr(sw[0], get_wordnet_pos(sw[1])) for sw in word_pos] return [x.lower() for x in lemm_words] print(normalize_text(''cats running ran cactus cactuses cacti community communities'')) # [''cat'', ''run'', ''ran'', ''cactus'', ''cactuses'', ''cacti'', ''community'', ''community''] print(normalize_text(''The cactus ran to the community to see the cats running around cacti between communities.'')) # [''the'', ''cactus'', ''run'', ''to'', ''the'', ''community'', ''to'', ''see'', ''the'', ''cat'', ''run'', ''around'', ''cactus'', ''between'', ''community'', ''.'']


Eche un vistazo a LemmaGen - biblioteca de código abierto escrita en C # 3.0.

Resultados para sus palabras de prueba ( http://lemmatise.ijs.si/Services )

  • gatos -> gato
  • corriendo
  • funcionó -> ejecutar
  • cactus
  • cactus -> cactus
  • cactus -> cactus
  • comunidad
  • comunidades -> comunidad

En Java, utilizo tartargus-bola de nieve a las palabras derivadas

Maven:

<dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-snowball</artifactId> <version>3.0.3</version> <scope>test</scope> </dependency>

Código de muestra:

SnowballProgram stemmer = new EnglishStemmer(); String[] words = new String[]{ "testing", "skincare", "eyecare", "eye", "worked", "read" }; for (String word : words) { stemmer.setCurrent(word); stemmer.stem(); //debug logger.info("Origin: " + word + " > " + stemmer.getCurrent());// result: test, skincar, eyecar, eye, work, read }



Haga una búsqueda por Lucene, no estoy seguro si hay un puerto PHP pero sé que Lucene está disponible para muchas plataformas. Lucene es una biblioteca de indexación y búsqueda OSS (de Apache). Naturalmente, esto y los extras de la comunidad podrían tener algo interesante que ver. Por lo menos, puede aprender cómo se hace en un idioma para que pueda traducir la "idea" en PHP.


La página oficial de Martin Porter contiene un Porter Stemmer en PHP y en otros idiomas .

Si realmente te tomas en serio la buena derivación, aunque vas a necesitar comenzar con algo como el algoritmo Porter, refínalo agregando reglas para corregir los casos incorrectos comunes a tu conjunto de datos, y finalmente agrega muchas excepciones a las reglas. . Esto se puede implementar fácilmente con pares clave / valor (dbm / hash / dictionaries) donde la clave es la palabra para buscar y el valor es la palabra derivada para reemplazar el original. Un motor de búsqueda comercial en el que trabajé una vez terminó con 800 excepciones a un algoritmo Porter modificado.



Los debates entre el lematizador y el lematizador continúan. Se trata de preferir la precisión a la eficiencia. Debería lematizar para lograr unidades lingüísticamente significativas y utilizar el mínimo jugo de computación y aún así indexar una palabra y sus variaciones bajo la misma clave.

Ver Stemmers vs Lemmatizers

Aquí hay un ejemplo con python NLTK:

>>> sent = "cats running ran cactus cactuses cacti community communities" >>> from nltk.stem import PorterStemmer, WordNetLemmatizer >>> >>> port = PorterStemmer() >>> " ".join([port.stem(i) for i in sent.split()]) ''cat run ran cactu cactus cacti commun commun'' >>> >>> wnl = WordNetLemmatizer() >>> " ".join([wnl.lemmatize(i) for i in sent.split()]) ''cat running ran cactus cactus cactus community community''


Martin Porter escribió Snowball (un lenguaje para algoritmos de derivación) y reescribió el "English Stemmer" en Snowball. Hay un English Stemmer para C y Java.

Él explícitamente declara que el Porter Stemmer ha sido reimplantado solo por razones históricas, por lo que las pruebas que demuestren la corrección contra el Porter Stemmer le darán resultados que usted (debería) ya conocer.

De http://tartarus.org/~martin/PorterStemmer/index.html (el énfasis es mío)

El proyectil Porter debe considerarse como " congelado ", es decir, estrictamente definido y no susceptible de modificaciones adicionales. Como un tallo, es ligeramente inferior al de Snowball English o Porter2, que se deriva de él y que está sujeto a mejoras ocasionales. Para el trabajo práctico, por lo tanto, se recomienda el nuevo generador de bolas Snowball. El proyectil Porter es apropiado para el trabajo de investigación de IR que involucra el tallo donde los experimentos deben ser exactamente repetibles.

El Dr. Porter sugiere usar los catarsis en inglés o en Porter2 en lugar de usar el stemmer Porter. El tallo inglés es lo que realmente se usa en el sitio de demostración como @StompChicken ha respondido antes.


Mire en WordNet, una gran base de datos léxica para el idioma inglés:

WordNet

Hay API para acceder a ella en varios idiomas.


Podrías usar la letalidad Morpha. UW ha subido morpha stemmer a Maven central si planea usarlo desde una aplicación Java. Hay un contenedor que hace que sea mucho más fácil de usar. Solo necesita agregarlo como dependencia y usar la clase edu.washington.cs.knowitall.morpha.MorphaStemmer . Las instancias son enhebrables (el JFlex original tenía campos de clase para variables locales innecesariamente). Crea una instancia de una clase y ejecuta morpha y la palabra que deseas contener.

new MorphaStemmer().morpha("climbed") // goes to "climb"


Probé tu lista de términos en este sitio de demostración de bola de nieve y los resultados se ven bien ...

  • gatos -> gato
  • corriendo -> ejecutar
  • corrió -> corrió
  • cactus -> cactus
  • cactus -> cactus
  • comunidad -> communiti
  • comunidades -> communiti

Se supone que un generador de látex convierte las formas de palabras inflexionadas en una raíz común. En realidad, no es tarea de un veterano convertir esa raíz en una palabra del diccionario "propia". Para eso, necesita observar analizadores morfológicos / ortográficos .

Creo que esta pregunta es más o menos lo mismo, y la respuesta de Kaarel a esa pregunta es de dónde tomé el segundo enlace.


Prueba este aquí: http://www.twinword.com/lemmatizer.php

Ingresé su consulta en la demostración "cats running ran cactus cactuses cacti community communities" y obtuve ["cat", "running", "run", "cactus", "cactus", "cactus", "community", "community"] con la bandera opcional ALL_TOKENS .

Código de muestra

Esta es una API para que pueda conectarse desde cualquier entorno. Aquí es cómo se verá la llamada PHP REST.

// These code snippets use an open-source library. http://unirest.io/php $response = Unirest/Request::post([ENDPOINT], array( "X-Mashape-Key" => [API KEY], "Content-Type" => "application/x-www-form-urlencoded", "Accept" => "application/json" ), array( "text" => "cats running ran cactus cactuses cacti community communities" ) );


Si conoce Python, The Natural Language Toolkit (NLTK) tiene un lemmatizador muy poderoso que hace uso de WordNet .

Tenga en cuenta que si está utilizando este lemmatizador por primera vez, debe descargar el corpus antes de usarlo. Esto se puede hacer por:

>>> import nltk >>> nltk.download(''wordnet'')

Sólo tienes que hacerlo una vez. Suponiendo que ya ha descargado el corpus, funciona así:

>>> from nltk.stem.wordnet import WordNetLemmatizer >>> lmtzr = WordNetLemmatizer() >>> lmtzr.lemmatize(''cars'') ''car'' >>> lmtzr.lemmatize(''feet'') ''foot'' >>> lmtzr.lemmatize(''people'') ''people'' >>> lmtzr.lemmatize(''fantasized'',''v'') ''fantasize''

Hay otros lematizadores en el módulo nltk.stem , pero no los he probado yo mismo.


Si puedo citar mi respuesta a la pregunta que StompChicken mencionó:

El problema central aquí es que los algoritmos de derivación operan sobre una base fonética sin una comprensión real del idioma con el que están trabajando.

Como no comprenden el idioma y no se ejecutan desde un diccionario de términos, no tienen forma de reconocer y responder adecuadamente a casos irregulares, como "ejecutar" / "ejecutar".

Si necesita manejar casos irregulares, tendrá que elegir un enfoque diferente o aumentar su derivación con su propio diccionario personalizado de correcciones para ejecutar después de que el tallador haya hecho su trabajo.


Yo uso stanford nlp para realizar la lematización. He estado atrapado con un problema similar en los últimos días. Todo gracias a para ayudarme a resolver el problema.

import java.util.*; import edu.stanford.nlp.pipeline.*; import edu.stanford.nlp.ling.*; import edu.stanford.nlp.ling.CoreAnnotations.*; public class example { public static void main(String[] args) { Properties props = new Properties(); props.put("annotators", "tokenize, ssplit, pos, lemma"); pipeline = new StanfordCoreNLP(props, false); String text = /* the string you want */; Annotation document = pipeline.process(text); for(CoreMap sentence: document.get(SentencesAnnotation.class)) { for(CoreLabel token: sentence.get(TokensAnnotation.class)) { String word = token.get(TextAnnotation.class); String lemma = token.get(LemmaAnnotation.class); System.out.println("lemmatized version :" + lemma); } } } }

También puede ser una buena idea usar palabras vacías para minimizar los mensajes de salida si se usa más adelante en el clasificador. Por favor, eche un vistazo a la extensión coreNlp escrita por John Conwell.



df_plots = pd.read_excel("Plot Summary.xlsx", index_col = 0) df_plots # Printing first sentence of first row and last sentence of last row nltk.sent_tokenize(df_plots.loc[1].Plot)[0] + nltk.sent_tokenize(df_plots.loc[len(df)].Plot)[-1] # Calculating length of all plots by words df_plots["Length"] = df_plots.Plot.apply(lambda x : len(nltk.word_tokenize(x))) print("Longest plot is for season"), print(df_plots.Length.idxmax()) print("Shortest plot is for season"), print(df_plots.Length.idxmin()) #What is this show about? (What are the top 3 words used , excluding the #stop words, in all the #seasons combined) word_sample = list(["struggled", "died"]) word_list = nltk.pos_tag(word_sample) [wnl.lemmatize(str(word_list[index][0]), pos = word_list[index][1][0].lower()) for index in range(len(word_list))] # Figure out the stop words stop = (stopwords.words(''english'')) # Tokenize all the plots df_plots["Tokenized"] = df_plots.Plot.apply(lambda x : nltk.word_tokenize(x.lower())) # Remove the stop words df_plots["Filtered"] = df_plots.Tokenized.apply(lambda x : (word for word in x if word not in stop)) # Lemmatize each word wnl = WordNetLemmatizer() df_plots["POS"] = df_plots.Filtered.apply(lambda x : nltk.pos_tag(list(x))) # df_plots["POS"] = df_plots.POS.apply(lambda x : ((word[1] = word[1][0] for word in word_list) for word_list in x)) df_plots["Lemmatized"] = df_plots.POS.apply(lambda x : (wnl.lemmatize(x[index][0], pos = str(x[index][1][0]).lower()) for index in range(len(list(x))))) #Which Season had the highest screenplay of "Jesse" compared to "Walt"  #Screenplay of Jesse =(Occurences of "Jesse")/(Occurences of "Jesse"+ #Occurences of "Walt") df_plots.groupby("Season").Tokenized.sum() df_plots["Share"] = df_plots.groupby("Season").Tokenized.sum().apply(lambda x : float(x.count("jesse") * 100)/float(x.count("jesse") + x.count("walter") + x.count("walt"))) print("The highest times Jesse was mentioned compared to Walter/Walt was in season"), print(df_plots["Share"].idxmax()) #float(df_plots.Tokenized.sum().count(''jesse'')) * 100 / #float((df_plots.Tokenized.sum().count(''jesse'') + #df_plots.Tokenized.sum().count(''walt'') + #df_plots.Tokenized.sum().count(''walter'')))