Nltk: La salida de Porter Stemmer es inconsistente con la de las implementaciones de referencia.

Creado en 17 ene. 2012  ·  8Comentarios  ·  Fuente: nltk/nltk

Recientemente utilicé el lematizador Porter de NLTK y descubrí algunas discrepancias entre su salida y la de otra versión del lematizador Porter que he usado. Siguiendo con estas discrepancias, descubrí que puede haber algunos problemas con la implementación de NLTK.

Hay varias implementaciones de referencia del lematizador Porter recopiladas por el propio Martin Porter aquí:

http://tartarus.org/~martin/PorterStemmer/

Probé el de Ruby para verificar la cordura del NLTK (toma una palabra de la salida estándar y escupe su forma derivada de inmediato, también en la salida estándar):

scripts $ ruby ​​porter_stemmer.rb
brillante
shini

Verifiqué esto con el NLTK:

scripts $ python
Python 2.6.1 (r261: 67515, 24 de junio de 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. compilación 5646)] en darwin
Escriba "ayuda", "derechos de autor", "créditos" o "licencia" para obtener más información.

        import nltk
        nltk.stem.porter.PorterStemmer().stem_word('shiny')

'shini'

Hasta ahora tan bueno. Y si comparo estos resultados con los resultados esperados (output.txt) proporcionados en la misma página para un archivo de dict de usuario de muestra (voc.txt), se ven bien:

scripts $ egrep -n '^ shiny $' voc.txt
18333: brillante
scripts $ egrep -n '^ shini $' output.txt
18333: shini

Pero si comparo sistemáticamente los resultados de NLTK con los del archivo de resultados esperados, veo muchas discrepancias (formato: palabra, derivación esperada adecuada, derivación NLTK incorrecta marcada con un asterisco):

scripts $ ./show_bad_stemming_in_nltk.py voc.txt output.txt
abadía abbei * abadía
abadías abbei * abadía
abed ab * abe
absey absei * absey
[...]
irónico * wri
ayer yesterdai * ayer
ayeres ayeres * ayer
yongrey yongrei * yongrey

La comprobación puntual con la implementación de referencia de Ruby confirma que los resultados de NLTK son, de hecho, el problema:

scripts $ ruby ​​porter_stemmer.rb
abadía
abbei
abadías
abbei
una cama
ab
absey
absei
irónico
torcido
el dia de ayer
Yesterdai
ayeres
Yesterdai
yongrey
yongrei

He adjuntado la lista completa de palabras para las que el lematizador Porter de NLTK proporciona resultados inesperados.

(Este error pertenece a la versión 2.0b9. Sospecho que existe en todas las versiones anteriores, pero no lo he confirmado).

Migrado desde http://code.google.com/p/nltk/issues/detail?id=625


comentarios anteriores

gregg.lind dijo, en 2011-02-09T20: 22: 57.000Z:

Estaría feliz de tomar este (antes del viernes), si nadie más lo quiere. He usado mucho este módulo. Gregg Lind

StevenBird1 dijo, en 2011-02-14T07: 14: 49.000Z:

Se adjuntan las correcciones de Stuart Robinson, enviadas a nltk-dev. Esto parece ser más ediciones de la versión anterior en lugar de una nueva versión de Ruby como se discutió originalmente. Antes de que se pueda incorporar esta nueva versión, necesitamos agregar un conjunto de casos de prueba a test / stem.doctest.

goodfirstbug

Comentario más útil

@paulproteus - finalmente resuelto

Todos 8 comentarios

Solo puse la etiqueta "goodfirstbug" en este. El "buen primer error" sería agregar un montón de casos de prueba a stem.doctest (https://github.com/nltk/nltk/blob/master/nltk/test/stem.doctest), si desea fusionar en los arreglos de Stuart también, ¡eso sería genial!

Hola a todos, especialmente a @alexrudnick , ¿debería marcarse esto como resuelto ahora?

Tras un vistazo, parece que no, aún no se ha resuelto. Pero me gustaría saber de un mantenedor.

@paulproteus - finalmente resuelto

Tenga en cuenta que el comportamiento del lematizador _default_ a partir de mi PR que Steven acaba de fusionar no ha cambiado; debe pasar explícitamente mode=PorterStemmer.MARTIN_EXTENSIONS al constructor PorterStemmer para obtener un comportamiento que sea consistente con las implementaciones de referencia de Martin (que son en sí mismas inconsistentes con el algoritmo original de Martin).

Podría decirse que sería mejor tener MARTIN_EXTENSIONS como modo predeterminado (por coherencia con las implementaciones de referencia), ya que los usuarios esperarán que algo llamado PorterStemmer comporte de forma inmediata como las implementaciones de referencia de Martin. El problema es que eso sería una ruptura de compatibilidad con versiones anteriores, y una desagradablemente no obvia; Alguien que use la implementación anterior de NLTK y actualice NLTK podría no darse cuenta durante mucho tiempo de que solo algunos de sus vástagos han cambiado, posiblemente introduciendo errores sutiles según su caso de uso. Otra opción es no tener un valor predeterminado en absoluto y requerir que cada usuario lea los documentos en los diferentes modos y elija explícitamente cuál usar. Esto también rompería la compatibilidad con versiones anteriores, pero lo haría de una manera _obvia_ (solo intentar crear una instancia del derivador de la forma anterior explotaría) para que las personas que realicen actualizaciones sin leer las notas de la versión no se vean atrapadas. Ese enfoque evitaría cualquiera de los malos escenarios anteriores, pero a costa de exigir más trabajo inicial a cada nuevo usuario de la lectora.

Ninguna de las opciones es perfecta. Opté por tener NLTK_EXTENSIONS como valor predeterminado, pero hay espacio para no estar de acuerdo. ¿Alguien tiene una opinión?

@ExplodingCabbage : prefiero su última opción, no predeterminada, y lo hago con la próxima versión principal (no la versión secundaria donde aparecerá su trabajo por primera vez), con advertencias adecuadas en las notas de la versión. Creo que sería bueno que las personas se vieran obligadas a leer los documentos y beneficiarse de su trabajo. Tengo curiosidad por saber qué piensan los demás.

Hola chicos,

He estado escribiendo un motor de búsqueda con el PorterStemmer predeterminado en nltk, sin saber que no se comporta de la misma manera que muchas otras implementaciones de Stemmer de Porter. Ahora que estoy trabajando en el front-end usando Javascript, me encuentro con errores en los que el front-end y mi back-end son las palabras madre de manera diferente. Me preguntaba qué debería mirar si necesito recrear el comportamiento predeterminado de PorterStemmer de nltk en Javascript para poder ejecutarlo en el navegador. Esperaba que tal vez alguien (¿tal vez @ExplodingCabbage ?) Pudiera señalarme la dirección correcta.

Realmente no tengo tiempo para volver a indexar todo con el modo MARTIN_EXTENSIONS, ya que llevaría semanas hacerlo ...

@josephcc porter.py básicamente no tiene dependencias y no está haciendo nada profundo o mágico, solo una larga serie de manipulaciones de cadenas. Solo querrá portar la clase PorterStemmer a JavaScript, conservando solo las ramas if self.mode == self.NLTK_EXTENSIONS y descartando la lógica de las demás.

No es una tarea de 5 minutos o infalible, es cierto, pero es factible. También consulte PorterTest en https://github.com/nltk/nltk/blob/develop/nltk/test/unit/test_stem.py y considere ejecutar los casos de prueba allí contra su implementación de JavaScript para verificar la corrección de tu trabajo.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

libingnan54321 picture libingnan54321  ·  3Comentarios

Chris00 picture Chris00  ·  3Comentarios

jeryini picture jeryini  ·  5Comentarios

talbaumel picture talbaumel  ·  4Comentarios

alvations picture alvations  ·  4Comentarios