Logistische Regression mit falschen Ergebnissen

8

Ich arbeite an einer Website, auf der ich die Ergebnisse von Schachspielen sammle, die Leute gespielt haben. Betrachtet man die Bewertungen des Spielers und den Unterschied zwischen seiner Bewertung und der seines Gegners, zeichne ich ein Diagramm mit Punkten, die Gewinn (grün), Unentschieden (blau) und Verlust (rot) darstellen.

Mit diesen Informationen habe ich auch einen logistischen Regressionsalgorithmus implementiert, um die Cutoffs für Gewinnen und Gewinnen / Zeichnen zu kategorisieren. Wenn ich die Bewertung und die Differenz als meine beiden Merkmale benutze, bekomme ich einen Klassifikator und zeichne dann die Grenzen auf dem Diagramm, wo der Klassifikator seine Vorhersage ändert.

Mein Code für Gradientenabfall, die Kostenfunktion und die Sigmoid-Funktion sind unten.

%Vor%

Wenn ich dies auf dem Datensatz überprüfe, der mein eigenes Schachprofil repräsentiert, bekomme ich vernünftige Ergebnisse, mit denen ich glücklich sein kann:

Für eine Weile war ich glücklich. Alle Beispiele, die ich versuchte, ergaben interessante Diagramme. Dann probierte ich einen Spieler, Kevin Cao, der über 250 Turniere auf seinen Namen hatte, und somit 1000+ Spiele, für ein sehr großes Trainingsset. Das Ergebnis war offensichtlich falsch:

Nun, das war nicht gut. Also habe ich die anfängliche Lernrate von 1.0 auf 100.0 als erste Idee erhöht. Das hat die richtigen Ergebnisse für Kevin:

Leider habe ich, als ich es dann an mir selbst und an meinem kleineren Datensatz ausprobierte, das seltsame Phänomen, dass es für eine der Vorhersagen nur eine flache Linie bei 0 gab:

Ich überprüfte Theta, und es sagte, es war [[2.3707682771730836], [21.22408286825226], [-19081.906528679192]]. Die dritte Trainingsvariable (wirklich zweit, da x_0 = 1) ist der Unterschied in den Bewertungen. Wenn die Differenz also nur das kleinste Bit positiv ist, geht die Formel für die logistische Regression sehr negativ und die Sigmoidfunktion sagt y = 0 voraus Unterschied ist nur das ein bisschen positive, ähnlich springt es weit nach oben und sagt y = 1 voraus.

Ich habe die anfängliche Lernrate von 100.0 auf 1.0 reduziert und stattdessen beschlossen, sie langsamer zu reduzieren. Anstatt es um den Faktor zehn zu reduzieren, wenn die Kostenfunktion steigt, habe ich es um den Faktor zwei reduziert.

Leider hat dies das Ergebnis für mich überhaupt nicht verändert. Selbst wenn ich die Anzahl der Schleifen des Gradientenabfalls von 100 auf 1000 erhöht hätte, hätte ich immer noch das falsche Ergebnis vorhergesagt.

Ich bin immer noch ziemlich Anfänger in der logistischen Regression (ich habe gerade den Kurs zum maschinellen Lernen auf Kurs beendet und ich versuche zum ersten Mal, einen der Algorithmen, die ich dort gelernt habe, zu implementieren), also habe ich ungefähr das Ausmaß erreicht meine Intuition. Wenn mir jemand helfen würde, herauszufinden, was hier falsch läuft, was ich falsch mache und wie ich es beheben kann, wäre ich sehr dankbar.

EDIT: Ich habe es auch auf einem anderen Datensatz versucht, der ungefähr 300 Datenpunkte hatte, und wieder einmal eine flache grüne Linie und eine normale blaue Linie bekommen. Der Algorithmus ist im Grunde genommen der gleiche für beide, nur einige unterschiedliche Ergebnisse für y, weil ich Multi-Class-Klassifikation mache.

BEARBEITEN: Da die Leute danach gefragt haben, sind hier J, Alpha und Theta für jede Iteration des Gradientenabfalls für die Linie, die flach ist:

%Vor%

Für denjenigen, der eine richtige Vorhersage erstellt:

%Vor%

EDIT: Ich habe festgestellt, dass bei der ersten Iteration die Hypothese immer 0.5 voraussagt, da das Theta alles 0 ist. Aber danach sagt es immer 1 oder 0 voraus (0.00001 oder 0.99999, um Logarithmen zu vermeiden, die in meinem Code nicht existieren). Das erscheint mir nicht richtig - viel zu selbstbewusst - und ist wahrscheinlich der Schlüssel, warum das nicht funktioniert.

    
Andrew Latham 02.12.2012, 20:57
quelle

4 Antworten

3

Es gibt ein paar Dinge über Ihre Implementierung, die ein wenig nicht standard sind.

  1. Zunächst wird das logistische Regressionsziel typischerweise als Minimierungsproblem von

    angegeben

    lr(x[n],y[n])=log(1+exp(-y[n]*dot(w[n],x[n]))) Dabei ist y[n] entweder 1 oder -1

    Sie scheinen die äquivalente Maximierungsproblemformulierung von

    zu verwenden

    lr(x[n],y[n])=-y[n]*log(1+exp(-dot(w[n],x[n])))+(1-y[n])*(-dot(w[n],x[n])-log(1+exp(-dot(w[n],x[n])))

    wobei y[n] entweder 0 oder 1 ist (y [n] = 0 in dieser Formulierung ist das Äquivalent von y [n] = 1 in der ersten Formulierung).

    Sie sollten also sicherstellen, dass Ihre Labels in Ihrem Dataset 0 oder 1 und nicht 1 oder -1 sind.

  2. Als nächstes wird das LR-Ziel normalerweise nicht durch m (die Größe des Datensatzes) geteilt. Dieser Skalierungsfaktor ist falsch, wenn Sie die logistische Regression als probabilistisches Modell betrachten.

  3. Schließlich haben Sie vielleicht einige numerische Probleme mit Ihrer Implementierung (die Sie in der g-Funktion zu korrigieren versuchten). Leon Bottous sgd-Code (http://leon.bottou.org/projects/sgd) hat einige stabilere Berechnungen der Verlustfunktion und der Ableitung wie folgt (im C-Code - er verwendet die erste LR-Formulierung, die ich erwähne):

    %Vor%

Sie sollten auch eine l-bfgs-Standardroutine in Betracht ziehen (ich bin mit Ruby-Implementierungen nicht vertraut), damit Sie sich darauf konzentrieren können, die Ziel- und Gradientenberechnungen zu korrigieren und sich nicht um Lernraten zu kümmern.

    
user1149913 11.12.2012 03:48
quelle
1

ein paar Gedanken:

  • Ich denke, es wäre hilfreich, wenn Sie die Werte einiger Iterationen von J() und alpha anzeigen könnten.
  • Nehmen Sie eine Konstante (Bias) als Feature? Wenn ich mich richtig erinnere, wenn Sie dies nicht tun, wird Ihre (gerade) Zeile von h() == 0.5 gezwungen, durch Null zu gehen

  • Ihre Funktion J() sieht so aus, als würde sie die negative Log-Wahrscheinlichkeit zurückgeben (die Sie daher minimieren ) möchten. Sie verringern jedoch die Lernrate if (oldJ < newJ) , d.h. wenn J() größer, d. H. Schlechter, wurde.

Andre Holzner 07.12.2012 20:06
quelle
0

Gleitkommazahlen:

Versuchen Sie das? Equal Vergleich zwischen Schwimmern macht keinen großen Sinn für mich.

%Vor%

Merkmalskalierung

Sie haben erwähnt, dass Sie zwei Funktionen verwenden, ich nehme an, dass sie die eigene Bewertung des Spielers und die Bewertung diff sind. Ist das richtig?

Erwägen Sie auch die Verwendung einer Skalierung von Features als Datenvorverarbeitungsschritt, z. B.

. oder Sie können die Standardisierungsmethode ausführen, indem Sie die Werte jedes Features in den Daten auf Null-Mittelwert und Einheiten-Varianz setzen.

Fragen:

  • Was ist der Unterschied zwischen Ihrer blauen und grünen Linie in Ihren Grafiken?
  • Haben Sie versucht, mit einer sehr kleinen Lernrate zu beginnen, z. B. 0,01 oder 0,001?
  • Was wäre das Verhalten, wenn Sie nur eine feste Lernrate verwenden? Versuchen Sie 0,001, 0,01, 0,1, 0,5, 1, 10 usw. Bitte geben Sie hier Ihr Ergebnis an.
greeness 07.12.2012 19:31
quelle
0

Anstatt mit Ihrer Lernrate zu spielen, denke ich, dass Sie Ihren anfänglichen Datensatz mit Hilfe der Feature-Normalisierung ((X-mu) / sigma) normalisieren und dann die Operation ausführen müssen, die Sie durchführen möchten.

Ohne Feature-Normalisierung wird der Gradientenabstieg für große Datenmengen bei ungewöhnlichen Verhalten fehlerhaft.

    
Sumit Kumar Saha 01.02.2016 14:48
quelle