Nltk Sprachmodell (ngram) berechnen das Problem eines Wortes aus dem Kontext

Ich benutze Python und NLTK, um ein Sprachmodell wie folgt zu erstellen:

from nltk.corpus import brown from nltk.probability import LidstoneProbDist, WittenBellProbDist estimator = lambda fdist, bins: LidstoneProbDist(fdist, 0.2) lm = NgramModel(3, brown.words(categories='news'), estimator) # Thanks to miku, I fixed this problem print lm.prob("word", ["This is a context which generates a word"]) >> 0.00493261081006 # But I got another program like this one... print lm.prob("b", ["This is a context which generates a word"]) 

Aber es scheint nicht zu funktionieren. Das Ergebnis ist wie folgt:

 >>> print lm.prob("word", "This is a context which generates a word") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python2.6/dist-packages/nltk/model/ngram.py", line 79, in prob return self._alpha(context) * self._backoff.prob(word, context[1:]) File "/usr/local/lib/python2.6/dist-packages/nltk/model/ngram.py", line 79, in prob return self._alpha(context) * self._backoff.prob(word, context[1:]) File "/usr/local/lib/python2.6/dist-packages/nltk/model/ngram.py", line 82, in prob "context %s" % (word, ' '.join(context))) TypeError: not all arguments converted during string formatting 

Kann mir jemand helfen? Vielen Dank!

4 Solutions collect form web for “Nltk Sprachmodell (ngram) berechnen das Problem eines Wortes aus dem Kontext”

Schnelle Lösung:

 print lm.prob("word", ["This is a context which generates a word"]) # => 0.00493261081006 

Ich weiß, diese Frage ist alt, aber es öffnet sich jedes Mal, wenn ich google nltk's NgramModel Klasse. NgramModels Problemimplementierung ist ein wenig unintuitiv. Der Asker ist verwirrt. Soweit ich sagen kann, sind die Antworten nicht großartig. Da ich NPCModel oft nicht benutze, bedeutet das, dass ich verwirrt bin. Nicht mehr.

Der Quellcode lebt hier: https://github.com/nltk/nltk/blob/master/nltk/model/ngram.py . Hier ist die Definition von NgramModels prob-Methode:

 def prob(self, word, context): """ Evaluate the probability of this word in this context using Katz Backoff. :param word: the word to get the probability of :type word: str :param context: the context the word is in :type context: list(str) """ context = tuple(context) if (context + (word,) in self._ngrams) or (self._n == 1): return self[context].prob(word) else: return self._alpha(context) * self._backoff.prob(word, context[1:]) 

( Hinweis : 'Selbst [Kontext] .prob (Wort) ist gleichbedeutend mit' self._model [context] .prob (Wort) ')

Okay. Jetzt wissen wir wenigstens was wir suchen. Was muss Kontext sein? Schauen wir uns einen Auszug aus dem Konstruktor an:

 for sent in train: for ngram in ingrams(chain(self._lpad, sent, self._rpad), n): self._ngrams.add(ngram) context = tuple(ngram[:-1]) token = ngram[-1] cfd[context].inc(token) if not estimator_args and not estimator_kwargs: self._model = ConditionalProbDist(cfd, estimator, len(cfd)) else: self._model = ConditionalProbDist(cfd, estimator, *estimator_args, **estimator_kwargs) 

In Ordung. Der Konstruktor erzeugt aus einer bedingten Häufigkeitsverteilung eine bedingte Wahrscheinlichkeitsverteilung (self._model), deren "Kontext" Tupel von Unigrammen ist. Dies sagt uns, dass "Kontext" kein String oder eine Liste mit einer einzigen Mehrwortfolge sein sollte. "Kontext" muss etwas, das mit Unigrammen existiert. In der Tat ist die Anforderung ein wenig strenger. Diese Tupel oder Listen müssen die Größe n-1 haben. Denken Sie daran so. Du hast es gesagt, dass es ein Trigramm-Modell ist. Sie geben ihm den passenden Kontext für Trigramme.

Lassen Sie uns dies in Aktion mit einem einfacheren Beispiel sehen:

 >>> import nltk >>> obs = 'the rain in spain falls mainly in the plains'.split() >>> lm = nltk.NgramModel(2, obs, estimator=nltk.MLEProbDist) >>> lm.prob('rain', 'the') #wrong 0.0 >>> lm.prob('rain', ['the']) #right 0.5 >>> lm.prob('spain', 'rain in') #wrong 0.0 >>> lm.prob('spain', ['rain in']) #wrong '''long exception''' >>> lm.prob('spain', ['rain', 'in']) #right 1.0 

(Als Nebennote, eigentlich versuchst du alles mit MLE zu tun, wie dein Schätzer in NgramModel eine schlechte Idee ist, die Dinge fallen auseinander, ich garantiere es.)

Wie für die ursprüngliche Frage, nehme ich an, dass meine beste Vermutung, was OP will, ist das:

 print lm.prob("word", "generates a".split()) print lm.prob("b", "generates a".split()) 

… aber es gibt so viele Missverständnisse, die hier vor sich gehen, dass ich nicht sagen kann, was er eigentlich versucht hat zu tun.

Im Hinblick auf Ihre zweite Frage: das passiert, weil "b" nicht in der Brown Corpus Kategorie news , wie Sie überprüfen können mit:

 >>> 'b' in brown.words(categories='news') False 

wohingegen

 >>> 'word' in brown.words(categories='news') True 

Ich gebe zu, dass die Fehlermeldung sehr kryptisch ist, also möchtest du einen Fehlerbericht mit den NLTK-Autoren ablegen.

Ich würde von NLTKs NgramModel vorläufig weg bleiben. Es gibt derzeit einen Glättungsfehler, der das Modell dazu veranlasst, die Wahrscheinlichkeiten stark zu überschätzen, wenn n> 1 ist. Wenn du mit NgramModel am Ende bist, solltest du auf jeden Fall den im git Issue Tracker erwähnten Update anwenden: https://github.com/nltk/nltk/issues/367

  • Nltk Schnittstelle zum Stanford Parser
  • Split Worte auf Grenze
  • Python: Begegnung Probleme in Satzsegmenter, Wort-Tokenizer und Part-of-Speech-Tagger
  • Erstellen von Wortformen mit Python
  • Stanford NER Tagger in NLTK
  • Wie erstelle ich eine Wortwolke aus einem Korpus in Python?
  • So verwenden Sie mehrere Versionen von Python ohne Deinstallation
  • TF-IDF-Implementierungen in Python
  • Semantische Verwandtschaft Algorithmen - python
  • Split Text in Absätze NLTK - Verwendung von nltk.tokenize.texttiling?
  • Wie man Zeit Datum Periode Informationen aus rohen Sätzen in Python zu extrahieren
  • Python ist die beste Programmiersprache der Welt.