Nltk: Die Ausgabe von Porter Stemmer stimmt nicht mit der von Referenzimplementierungen überein

Erstellt am 17. Jan. 2012  ·  8Kommentare  ·  Quelle: nltk/nltk

Ich habe vor kurzem den Porter-Stammer des NLTK verwendet und einige Diskrepanzen zwischen seiner Ausgabe und der einer anderen Version des Porter-Stammers entdeckt, die ich verwendet habe. Als ich diesen Diskrepanzen nachging, stellte ich fest, dass es einige Probleme bei der Implementierung des NLTK geben könnte.

Es gibt verschiedene Referenzimplementierungen des Porter Stemmers, die von Martin Porter selbst hier gesammelt wurden:

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

Ich habe den für Ruby ausprobiert, um den NLTK zu überprüfen (er nimmt ein Wort aus dem Standard heraus und spuckt seine gestammte Form sofort aus, auch auf Standard):

Skripte $ ruby ​​porter_stemmer.rb
glänzend
shini

Ich habe dies mit dem NLTK überprüft:

Skripte $ python
Python 2.6.1 (r261:67515, 24.06.2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. Build 5646)] auf darwin
Geben Sie "Hilfe", "Copyright", "Credits" oder "Lizenz" ein, um weitere Informationen zu erhalten.

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

'glänzen'

So weit, ist es gut. Und wenn ich diese Ergebnisse mit den erwarteten Ergebnissen (output.txt) vergleiche, die auf derselben Seite für eine Beispiel-Benutzer-Diktierdatei (voc.txt) bereitgestellt werden, sehen sie richtig aus:

Skripte $ egrep -n '^shiny$' voc.txt
18333: glänzend
Skripte $ egrep -n '^shini$' Ausgabe.txt
18333: Shini

Aber wenn ich die NLTK-Ergebnisse systematisch mit denen in der erwarteten Ergebnisdatei vergleiche, sehe ich viele Diskrepanzen (Format: Wort, korrektes erwartetes Stemming, schlechtes NLTK-Stemming mit Sternchen markiert):

Skripte $ ./show_bad_stemming_in_nltk.py voc.txt output.txt
abtei abbei *abtei
abteien abbei *abtei
bett ab *abe
absey absei *absey
[…]
weinen schief *wri
gestern gestern *gestern
gestern gestern *gestern
yongrey yongrei *yongrey

Ein Stichprobenvergleich mit der Ruby-Referenzimplementierung bestätigt, dass die NLTK-Ergebnisse tatsächlich das Problem sind:

Skripte $ ruby ​​porter_stemmer.rb
Abtei
abbei
Abteien
abbei
ein Bett
ab
absey
absei
weinen
trocken
gestern
gestern
gestern
gestern
yongrey
yongrei

Ich habe die vollständige Liste der Wörter beigefügt, für die der Porter-Stammer des NLTK unerwartete Ergebnisse liefert.

(Dieser Fehler bezieht sich auf Version 2.0b9. Ich vermute, dass er in allen früheren Versionen vorhanden ist, aber ich habe das nicht bestätigt.)

Migriert von http://code.google.com/p/nltk/issues/detail?id=625


frühere Kommentare

gregg.lind sagte am 2011-02-09T20:22:57.000Z:

Das nehme ich gerne (bis Freitag) an, wenn es sonst keiner will. Ich habe dieses Modul sehr oft verwendet. Gregg Lind

StevenBird1 sagte am 2011-02-14T07:14:49.000Z:

Beigefügt sind die Fixes von Stuart Robinson, die an nltk-dev gesendet wurden. Dies scheint eher eine weitere Bearbeitung der vorherigen Version zu sein als eine neue Portierung der Ruby-Version, wie ursprünglich besprochen. Bevor diese neue Version integriert werden kann, benötigen wir eine Reihe von Testfällen, die zu test/stem.doctest hinzugefügt werden.

goodfirstbug

Hilfreichster Kommentar

@paulproteus – endlich gelöst

Alle 8 Kommentare

Ich habe nur das Etikett "goodfirstbug" darauf gesetzt. Der "gute erste Fehler" wäre das Hinzufügen einer Reihe von Testfällen zu stem.doctest (https://github.com/nltk/nltk/blob/master/nltk/test/stem.doctest) - wenn du Lust hast, zusammenzufassen auch in Stuarts Fixes, das wäre toll!

Hallo zusammen , besonders

Auf den ersten Blick sieht es aus wie nein, es ist noch nicht gelöst. Würde aber gerne von einem Betreuer hören.

@paulproteus – endlich gelöst

Beachten Sie, dass das _default_ Stemmer-Verhalten aus meiner PR, die Steven gerade zusammengeführt hat, unverändert ist; Sie müssen mode=PorterStemmer.MARTIN_EXTENSIONS explizit an den PorterStemmer Konstruktor übergeben, um ein Verhalten zu erhalten, das mit Martins Referenzimplementierungen übereinstimmt (die selbst nicht mit Martins ursprünglichem Algorithmus übereinstimmen).

Es wäre wohl besser, MARTIN_EXTENSIONS als Standardmodus (für die Konsistenz mit den Referenzimplementierungen) zu verwenden, da Benutzer erwarten, dass sich etwas namens PorterStemmer wie Martins Referenzimplementierungen verhält. Das Problem ist, dass dies eine Abwärtskompatibilitätslücke wäre und eine unangenehme, nicht offensichtliche; jemand, der die vorherige Implementierung von NLTK verwendet und NLTK aktualisiert, könnte lange Zeit nicht bemerken, dass sich nur einige ihrer Stämme geändert haben, was möglicherweise je nach Anwendungsfall subtile Fehler einführt. Eine andere Möglichkeit besteht darin, überhaupt keinen Standardwert zu verwenden und von jedem Benutzer zu verlangen, die Dokumentation zu den verschiedenen Modi zu lesen und explizit auszuwählen, welcher verwendet werden soll. Dies würde auch die Abwärtskompatibilität beeinträchtigen, würde dies jedoch auf _offensichtliche_ Weise tun (nur der Versuch, den Stemmer auf die alte Weise zu instanziieren, würde explodieren), damit Leute, die Upgrades durchführen, ohne die Versionshinweise zu lesen, nicht erwischt werden. Dieser Ansatz würde eines der oben genannten schlechten Szenarien vermeiden, aber auf Kosten von mehr Vorarbeit von jedem neuen Benutzer des Stemmers.

Keine der Optionen ist perfekt. Ich habe mich für NLTK_EXTENSIONS als Standard entschieden, aber es gibt Raum, dem zu widersprechen. Hat jemand eine Meinung?

@ExplodingCabbage : Ich bevorzuge Ihre letzte Option, keine Standardeinstellung, und dies mit der nächsten Hauptversion (nicht der Nebenversion, in der Ihre Arbeit zuerst erscheinen wird), mit entsprechenden Warnungen in den Versionshinweisen. Ich denke, es wäre gut, wenn die Leute gezwungen wären, die Dokumente zu lesen und von Ihrer Arbeit zu profitieren. Ich bin gespannt, was andere denken.

Hallo Leute,

Ich habe ein Suchmaschinen-Backend mit dem Standard-PorterStemmer in nltk geschrieben, ohne zu wissen, dass es sich nicht so verhält wie viele andere Porter-Stemmer-Implementierungen. Jetzt, wo ich mit Javascript am Frontend arbeite, stoße ich auf Fehler, bei denen das Frontend und mein Backend Wörter unterschiedlich abstammen. Ich habe mich gefragt, was ich mir ansehen sollte, wenn ich das Standardverhalten von PorterStemmer von nltk in Javascript neu erstellen muss, damit ich es im Browser ausführen kann. Ich hatte gehofft, dass mir vielleicht jemand (vielleicht @ExplodingCabbage ?)

Ich habe wirklich keine Zeit, alles mit dem MARTIN_EXTENSIONS-Modus neu zu indizieren, da dies Wochen dauern würde ...

@josephcc porter.py hat im Grunde keine Abhängigkeiten und macht nichts Tiefgreifendes oder Magisches, nur eine lange Reihe von String-Manipulationen. Sie wollen einfach die Klasse PorterStemmer nach JavaScript portieren, nur die if self.mode == self.NLTK_EXTENSIONS Zweige beibehalten und die Logik von den anderen wegwerfen.

Zugegeben keine 5-Minuten-Aufgabe oder eine narrensichere, aber machbar. Schauen Sie sich auch PorterTest in https://github.com/nltk/nltk/blob/develop/nltk/test/unit/test_stem.py an und ziehen Sie in Betracht, die Testfälle dort gegen Ihre JavaScript-Implementierung auszuführen, um die Richtigkeit zu überprüfen Ihrer Arbeit.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

alvations picture alvations  ·  3Kommentare

vezeli picture vezeli  ·  3Kommentare

mwess picture mwess  ·  5Kommentare

Chris00 picture Chris00  ·  3Kommentare

alvations picture alvations  ·  4Kommentare