So erstellen Sie eine einfache Gradient-Descent-Algorithmus
Ich studiere einfache machine-learning-algorithmen, beginnen Sie mit einer einfachen Gradienten-Abstieg, aber ich habe einige Mühe versucht, es zu implementieren in python.
Hier ist das Beispiel, das ich bin versucht zu reproduzieren, ich habe Daten über Häuser, die mit dem (Wohnzimmer (in feet2), und die Anzahl der Schlafzimmer) mit dem daraus resultierenden Preis :
Wohnbereich (feet2) : 2104
#Schlafzimmer : 3
Preis (1000$s) : 400
Ich versuche zu tun, eine einfache regression mit Hilfe der Gradienten-Abstiegs-Methode, aber mein Algorithmus funktioniert nicht...
Die form des Algorithmus ist nicht mit Vektoren auf Zweck (ich bin versucht zu verstehen, es Schritt für Schritt).
i = 1
import sys
derror=sys.maxint
error = 0
step = 0.0001
dthresh = 0.1
import random
theta1 = random.random()
theta2 = random.random()
theta0 = random.random()
while derror>dthresh:
diff = 400 - theta0 - 2104 * theta1 - 3 * theta2
theta0 = theta0 + step * diff * 1
theta1 = theta1 + step * diff * 2104
theta2 = theta2 + step * diff * 3
hserror = diff**2/2
derror = abs(error - hserror)
error = hserror
print 'iteration : %d, error : %s' % (i, error)
i+=1
Ich verstehe Mathe, ich Baue eine Vorhersage-Funktion
$$h_{\theta}(x) = \theta_0 + \theta_1 x_1 + \theta_2 x_2$$ http://mathurl.com/hoy7ege.png
mit $x_1$ http://mathurl.com/2ga69bb.png und $x_2$ http://mathurl.com/2cbdldp.png die Variablen (Wohnfläche, Anzahl der Schlafzimmer) und $h_{\theta}(x)$ http://mathurl.com/jckw8ke.png der geschätzte Preis.
Ich bin mit dem Kosten-Funktion ($hserror$ http://mathurl.com/guuqjv5.png) (für einen Punkt) :
$$hserror = \frac{1}{2} (h_{\theta}(x) - y)^2$$ http://mathurl.com/hnrqtkf.png
Dies ist eine übliche problem, aber ich bin eher ein software-Ingenieur, und ich bin zu lernen, einen Schritt zu einer Zeit, können Sie mir sagen, was ist falsch ?
Ich habe es funktioniert mit diesem code :
data = {(2104, 3) : 400, (1600,3) : 330, (2400, 3) : 369, (1416, 2) : 232, (3000, 4) : 540}
for x in range(10):
i = 1
import sys
derror=sys.maxint
error = 0
step = 0.00000001
dthresh = 0.0000000001
import random
theta1 = random.random()*100
theta2 = random.random()*100
theta0 = random.random()*100
while derror>dthresh:
diff = 400 - (theta0 + 2104 * theta1 + 3 * theta2)
theta0 = theta0 + step * diff * 1
theta1 = theta1 + step * diff * 2104
theta2 = theta2 + step * diff * 3
hserror = diff**2/2
derror = abs(error - hserror)
error = hserror
#print 'iteration : %d, error : %s, derror : %s' % (i, error, derror)
i+=1
print ' theta0 : %f, theta1 : %f, theta2 : %f' % (theta0, theta1, theta2)
print ' done : %f' %(theta0 + 2104 * theta1 + 3*theta2)
die endet mit Antworten wie diese :
theta0 : 48.412337, theta1 : 0.094492, theta2 : 50.925579
done : 400.000043
theta0 : 0.574007, theta1 : 0.185363, theta2 : 3.140553
done : 400.000042
theta0 : 28.588457, theta1 : 0.041746, theta2 : 94.525769
done : 400.000043
theta0 : 42.240593, theta1 : 0.096398, theta2 : 51.645989
done : 400.000043
theta0 : 98.452431, theta1 : 0.136432, theta2 : 4.831866
done : 400.000043
theta0 : 18.022160, theta1 : 0.148059, theta2 : 23.487524
done : 400.000043
theta0 : 39.461977, theta1 : 0.097899, theta2 : 51.519412
done : 400.000042
theta0 : 40.979868, theta1 : 0.040312, theta2 : 91.401406
done : 400.000043
theta0 : 15.466259, theta1 : 0.111276, theta2 : 50.136221
done : 400.000043
theta0 : 72.380926, theta1 : 0.013814, theta2 : 99.517853
done : 400.000043
Du musst angemeldet sein, um einen Kommentar abzugeben.
Erste Problem ist, dass die Ausführung dieser mit nur einem Stück von Daten gibt Ihnen einen underdetermined-system... das heißt, es kann eine unendliche Anzahl von Lösungen. Mit drei Variablen, die Sie erwarten würden, haben mindestens 3 Datenpunkte, vorzugsweise wesentlich höher.
Zweitens mit gradient descent, wo die Schrittweite ist eine skalierte version der Farbverlauf ist nicht gewährleistet, dass Sie konvergieren, außer in einer kleinen Umgebung der Lösung. Sie können das Problem beheben, dass durch die Umstellung entweder zu einer festen Größe Schritt in Richtung des negativen Gradienten (langsam) oder eine linesearch in Richtung des negativen Gradienten ( schneller, aber etwas komplizierter)
So für festen Schritt Größe anstatt
Tun Sie dies
Ist es auch sieht aus wie Sie möglicherweise einen vorzeichenfehler in deiner Schritte.
Ich bin mir auch nicht sicher, dass derror ist eine gute stoppen Kriterien. (Aber stoppen Kriterien sind notorisch schwer zu bekommen, "rechts")
Mein letzter Punkt ist, dass die Gradienten-Abstieg ist schrecklich langsam für die parameter-fitting. Sie wollen wahrscheinlich verwenden, conjugate-gradient-oder Levenberg-Marquadt-Methoden statt. Ich vermute, dass diese beiden Methoden gibt es bereits für python in der numpy oder scipy-Pakete (die nicht Teil von python standardmäßig, aber sind ziemlich einfach zu installieren)