Nltk: Satz-Tokenizer teilt sich nicht richtig auf

Erstellt am 23. Nov. 2015  ·  5Kommentare  ·  Quelle: nltk/nltk

Ich denke, es gibt einen Fehler im Standardsatz-Tokenizer sent_tokenize . Das Problem ist, dass es in bestimmten Fällen keinen Text in Sätze aufteilt. In diesem Fall kann der Tokenizer den Text nicht in zwei Sätze aufteilen:

[sent for sent in nltk.sent_tokenize('Model wears size S. Fits size.')]

Dies gibt ['Model wears size S. Fits size.'] anstelle von ['Model wears size S.', 'Fits size.'] . Das Problem scheint aufzutreten, wenn der letzte String vor . nur ein Zeichen enthält. Wenn die Anzahl der Zeichen >= 2 beträgt, wird der Text korrekt aufgeteilt.

inactive tokenizer

Hilfreichster Kommentar

Ich möchte nur ein reales Beispiel aus

sent_tokenize('The weather is terrible, and my day was ok. You are supposed to take your medicine.')

Ausgabe

['The weather is terrible, and my day was ok. You are supposed to take your medicine.']

Es bestätigte, dass nltk k. als Satztrennzeichen erkannte.

Alle 5 Kommentare

Dies scheint im Satz-Tokenizer sehr schwer zu beheben, wenn man bedenkt, dass S. Fits ein Vor- und Nachname einer Person sein kann.

Ich denke, der Weg besteht darin, den standardmäßigen NLTK-Satz-Tokenizer unterzuordnen oder zu kopieren und einzufügen und ihn an Ihre Anwendung anzupassen. Wenn Sie beispielsweise solche Personennamen im Text nicht erwarten, entfernen Sie Regeln, die Personennamen behandeln. Eine andere Möglichkeit besteht darin, einen Workaround zu verwenden, wie z. B. vor der Tokenisierung size <X> durch size_<X> ersetzen und sie wieder zu ersetzen, nachdem der Text in Sätze aufgeteilt wurde.

Hmmm. Habe es gerade nochmal versucht. Der erste Fall, den ich vorgestellt habe, ist also die Aufteilung nicht richtig. Aber wenn ich verschiedene Zeichen verwende, dann teilt es sich manchmal ! Deshalb habe ich diesen Schnelltest geschrieben:

import nltk
import pprint

pp = pprint.PrettyPrinter(indent=4)
s = 'Test {}. Test {}.'
[nltk.sent_tokenize(s.format(char, char)) for char in 'abcdefghijklmnopqrstuvwxyz']
[pp.pprint(nltk.sent_tokenize(s.format(char, char))) for char in 'abcdefghijklmnopqrstuvwxyz']

Ausgabe:

['Test a.', 'Test a.']
['Test b.', 'Test b.']
['Test c. Test c.']
['Test d. Test d.']
['Test e. Test e.']
['Test f. Test f.']
['Test g. Test g.']
['Test h. Test h.']
['Test i.', 'Test i.']
['Test j.', 'Test j.']
['Test k. Test k.']
['Test l. Test l.']
['Test m. Test m.']
['Test n. Test n.']
['Test o.', 'Test o.']
['Test p. Test p.']
['Test q.', 'Test q.']
['Test r. Test r.']
['Test s. Test s.']
['Test t. Test t.']
['Test u.', 'Test u.']
['Test v. Test v.']
['Test w. Test w.']
['Test x.', 'Test x.']
['Test y.', 'Test y.']
['Test z.', 'Test z.']

@kmike , wie Sie sehen können, ist es sehr inkonsistent.

@JernejJerin Es ist kein regelbasierter Tokenizer, so dass er die "Regeln" der Aufteilung nicht mit einer Regex-ähnlichen Erklärung kontrollieren / erklären kann.

Der zum Trainieren des sent_tokenizer Algorithmus ist der Punkt-Algorithmus von Kiss und Strunk (2006) . Es ist ein statistisches System, das versucht, Satzgrenzen zu lernen, also ist es nicht perfekt, aber es stimmt mit den vom Modell generierten Wahrscheinlichkeiten überein (aber nicht mit den notwendigen menschenähnlichen Regeln).

Ich möchte nur ein reales Beispiel aus

sent_tokenize('The weather is terrible, and my day was ok. You are supposed to take your medicine.')

Ausgabe

['The weather is terrible, and my day was ok. You are supposed to take your medicine.']

Es bestätigte, dass nltk k. als Satztrennzeichen erkannte.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen