Nltk: La sortie du stemmer de Porter est incohérente avec celle des implémentations de référence

Créé le 17 janv. 2012  ·  8Commentaires  ·  Source: nltk/nltk

J'ai récemment utilisé le stemmer Porter de NLTK et j'ai découvert des écarts entre sa sortie et celle d'une autre version du stemmer Porter que j'ai utilisé. Suite à ces divergences, j'ai découvert qu'il peut y avoir des problèmes avec la mise en œuvre du NLTK.

Il existe différentes implémentations de référence du stemmer Porter rassemblées par Martin Porter lui-même ici :

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

J'ai essayé celui pour Ruby de vérifier le bon sens du NLTK (il prend un mot de la sortie standard et crache immédiatement sa forme à base, également sur la sortie standard):

scripts $ ruby ​​porter_stemmer.rb
brillant
brillant

J'ai vérifié ceci contre le NLTK:

scripts $ python
Python 2.6.1 (r261:67515, 24 juin 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] sur darwin
Tapez "aide", "droit d'auteur", "crédits" ou "licence" pour plus d'informations.

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

'shini'

Jusqu'ici tout va bien. Et si je compare ces résultats aux résultats attendus (output.txt) fournis sur la même page pour un exemple de fichier dict utilisateur (voc.txt), ils semblent corrects :

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

Mais si je compare systématiquement les résultats NLTK à ceux du fichier de résultats attendus, je constate beaucoup d'incohérences (format : mot, radical attendu correct, radical NLTK incorrect marqué d'un astérisque) :

scripts $ ./show_bad_stemming_in_nltk.py voc.txt output.txt
abbaye abbaye * abbaye
abbayes abbaye *abbaye
abed ab *abe
absei absei *absey
[...]
tordu tordu *wri
hier hier * hier
hier hier * hier
yongrey yongrei *yongrey

Une vérification ponctuelle par rapport à l'implémentation de référence Ruby confirme que les résultats NLTK sont en fait le problème :

scripts $ ruby ​​porter_stemmer.rb
une abbaye
abbaye
abbayes
abbaye
un lit
un B
abbé
absei
se tordant
tordu
hier
hier
hier
hier
yongrey
yongrei

J'ai joint la liste complète des mots pour lesquels le stemmer Porter du NLTK fournit des résultats inattendus.

(Ce bogue concerne la version 2.0b9. Je soupçonne qu'il existe dans toutes les versions précédentes, mais je ne l'ai pas confirmé.)

Migré depuis http://code.google.com/p/nltk/issues/detail?id=625


commentaires précédents

gregg.lind a déclaré, le 2011-02-09T20:22:57.000Z :

Je serais heureux de prendre celui-ci (d'ici vendredi), si personne d'autre n'en veut. J'ai beaucoup utilisé ce module. Gregg Lind

StevenBird1 a déclaré, au 14-02-2011T07:14:49.000Z :

Ci-joint les correctifs de Stuart Robinson, envoyés à nltk-dev. Cela semble être des modifications supplémentaires de la version précédente plutôt qu'un nouveau portage de la version Ruby comme discuté à l'origine. Avant que cette nouvelle version puisse être incorporée, nous avons besoin d'un ensemble de cas de test ajouté à test/stem.doctest.

goodfirstbug

Commentaire le plus utile

@paulproteus – enfin résolu

Tous les 8 commentaires

Je viens de mettre le label "goodfirstbug" sur celui-ci. Le "bon premier bug" serait d'ajouter un tas de cas de test à stem.doctest (https://github.com/nltk/nltk/blob/master/nltk/test/stem.doctest) -- si vous avez envie de fusionner dans les correctifs de Stuart aussi, ce serait génial !

Salut à tous, en particulier @alexrudnick , cela devrait-il être marqué comme résolu maintenant ?

Après un survol, on dirait que non, ce n'est pas encore résolu. Mais j'aimerais entendre un responsable.

@paulproteus – enfin résolu

Notez que le comportement du stemmer _default_ à partir de mon PR que Steven vient de fusionner est inchangé; vous devez explicitement passer mode=PorterStemmer.MARTIN_EXTENSIONS au constructeur PorterStemmer pour obtenir un comportement cohérent avec les implémentations de référence de Martin (qui sont elles-mêmes incompatibles avec l'algorithme d'origine de Martin).

On peut soutenir qu'avoir MARTIN_EXTENSIONS comme mode par défaut (pour la cohérence avec les implémentations de référence) serait mieux, car les utilisateurs vont s'attendre à ce que quelque chose appelé PorterStemmer se comporte comme les implémentations de référence de Martin. Le problème est que ce serait une rupture de compatibilité descendante, et une rupture désagréablement non évidente; quelqu'un utilisant l'implémentation précédente de NLTK qui met à jour NLTK pourrait ne pas remarquer pendant longtemps que quelques-uns de leurs radicaux ont changé, introduisant éventuellement des bogues subtils en fonction de leur cas d'utilisation. Une autre option consiste à ne pas avoir de valeur par défaut du tout et à obliger chaque utilisateur à lire la documentation sur les différents modes et à choisir explicitement celui à utiliser. Cela briserait également la compatibilité descendante, mais le ferait d'une manière _évidente_ (le simple fait d'essayer d'instancier le stemmer à l'ancienne ferait exploser) afin que les personnes effectuant des mises à niveau sans lire les notes de version ne soient pas prises au dépourvu. Cette approche permettrait d'éviter l'un ou l'autre des mauvais scénarios ci-dessus, mais au prix d'exiger plus de travail en amont de chaque nouvel utilisateur du stemmer.

Aucune des options n'est parfaite. J'ai choisi d'avoir NLTK_EXTENSIONS par défaut, mais il y a de la place pour ne pas être d'accord. Quelqu'un a un avis ?

@ExplodingCabbage : Je privilégie votre dernière option, pas de valeur par défaut, et le faire avec la prochaine version majeure (pas la version mineure où votre travail apparaîtra pour la première fois), avec des avertissements appropriés dans les notes de version. Je pense qu'il serait bon que les gens soient obligés de lire les documents et de bénéficier de votre travail. Je suis curieux de savoir ce qu'en pensent les autres.

Salut les gars,

J'ai écrit un moteur de recherche avec le PorterStemmer par défaut dans nltk, sans savoir qu'il ne se comporte pas de la même manière que de nombreuses autres implémentations de stemmer de Porter. Maintenant que je travaille sur le front-end en utilisant Javascript, je rencontre des bogues où le front-end et mon back-end contiennent des mots différents. Je me demandais ce que je devrais regarder si je devais recréer le comportement par défaut de PorterStemmer de nltk en Javascript afin que je puisse l'exécuter dans le navigateur. J'espérais peut-être que quelqu'un (peut-être @ExplodingCabbage ?) pourrait me

Je n'ai vraiment pas le temps de tout ré-indexer avec le mode MARTIN_EXTENSIONS car cela prendrait des semaines pour le faire...

@josephcc porter.py n'a fondamentalement aucune dépendance et ne fait rien de profond ou de magique, juste une longue série de manipulations de chaînes. Vous voudrez juste porter la classe PorterStemmer vers JavaScript, en ne préservant que les branches if self.mode == self.NLTK_EXTENSIONS et en supprimant la logique des autres.

Pas une tâche de 5 minutes ou une tâche infaillible, certes, mais faisable. Consultez également PorterTest dans https://github.com/nltk/nltk/blob/develop/nltk/test/unit/test_stem.py et envisagez d'y exécuter les cas de test avec votre implémentation JavaScript pour vérifier l'exactitude de votre travail.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

BLKSerene picture BLKSerene  ·  4Commentaires

zdog234 picture zdog234  ·  3Commentaires

Chris00 picture Chris00  ·  3Commentaires

alvations picture alvations  ·  4Commentaires

DavidNemeskey picture DavidNemeskey  ·  4Commentaires