MaxEnt-Classifier (NLTK)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
nahadine
User
Beiträge: 2
Registriert: Sonntag 16. August 2009, 08:50

Allgemeines Hallo,

beim Training meines MaxEnt-Classifiers entstehen Ergebnisse, aus denen ich nicht recht schlau werde:

Code: Alles auswählen

>>> classifier = nltk.MaxentClassifier.train(train_set, max_iter = 10 )
  ==> Training (10 iterations)

      Iteration    Log Likelihood    Accuracy
      ---------------------------------------
             1          -2.19722        0.212
             2          -0.48707        0.792
             3               nan        0.857
             4               nan        0.029
             5               nan        0.024
             6               nan        0.024
             7               nan        0.024
             8               nan        0.024
             9               nan        0.024
         Final               nan        0.024
Kurze Google-Recherche ergibt: "nan" steht für "not a number" und weist meist auf eine Division durch Null hin. Bei der Berechnung der Log-Likelihood meiner Trainingsdaten wurde also vermutlich durch Null geteilt.

Um weiterzukommen, müsste man wissen, wie diese Berechnung genau abläuft. Kann mir an dieser Stelle jemand weiterhelfen oder hat, unabhängig davon, irgendeinen Erklärungsansatz?

Schon einmal vielen Dank,
Nadine
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Die Berechnung solltest Du in Python26\Lib\site-packages\nltk\classify\maxent.py finden.
MfG
HWK
BlackJack

@nahadine: Falls Dir hier niemand weiterhelfen kann, solltest Du Dich mit der Frage an das Forum und/oder den IRC vom NLTK-Projekt wenden. Das ist ja doch eher speziell und geht ziemlich in die Tiefe bei genau diesem Projekt und Fachgebiet.

http://www.nltk.org/ -> Getting Help
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Der relevante Code steht doch anderswo: Zeilen 79-82 in Python26\Lib\site-packages\nltk\classify\util.py.

Code: Alles auswählen

def log_likelihood(classifier, gold):
    results = classifier.batch_prob_classify([fs for (fs,l) in gold])
    ll = [pdist.prob(l) for ((fs,l), pdist) in zip(gold, results)]
    return math.log(float(sum(ll))/len(ll))
Wahrscheinlich wird NAN durch log(0) erzeugt. Vielleicht liegt es ja an den Daten? Die Accuracy scheint ja nicht besonders hoch zu sein.
MfG
HWK
nahadine
User
Beiträge: 2
Registriert: Sonntag 16. August 2009, 08:50

Wunderbar, dankeschön! Das ist schonmal die richtige Spur: Die Daten, auf denen ich den Classifier trainiere, sind noch nicht ganz vollständig. Und weil ich Training- und Testset immer mal wieder neu durchmische, kann tatsächlich zu unglücklichen Verteilungen kommen. Sehr niedrig frequente Label treten dann u.U. schmerzhaft selten auf.

Trotzdem, ich verstehe nicht ganz, wie hier

Code: Alles auswählen

    ll = [pdist.prob(l) for ((fs,l), pdist) in zip(gold, results)]
    return math.log(float(sum(ll))/len(ll))
eine Null ins Argument des Logarithmus geraten kann. Es wird immer Label l geben, für die

Code: Alles auswählen

pdist.prob(l) > 0
und damit auch

Code: Alles auswählen

float(sum(ll))/len(ll) > 0.

Und len(ll) > 0 ist ohnehin immer wahr.

Woher also die Null?


Abgesehen davon allerdings - juchee, wenn ich meine Trainingsdaten entsprechend zusammenstelle, funktioniert es wieder:

Code: Alles auswählen

 Iteration    Log Likelihood    Accuracy
      ---------------------------------------
             1          -2.07944        0.607
             2          -0.50503        0.836
             3          -0.39157        0.893
             4          -0.32261        0.925
             5          -0.27698        0.944
             6          -0.24441        0.955
             7          -0.21982        0.960
             8          -0.20048        0.964
             9          -0.18479        0.968
         Final          -0.17176        0.970
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Kann pdist.prob(l) auch < 0 werden? Dann könnte natürlich natürlich auch sum(ll) == 0 werden. Füge doch mal eine Print-Zeile vor der Return-Zeile ein und lass Dir Zwischenergebnisse ausgeben.
MfG
HWK
Antworten