2010-10-01 26 views
7

Basit bir degrade inişten başlayarak basit makine öğrenimi algoritmaları üzerinde çalışıyorum, ancak python'da uygulamaya çalışırken bazı sorun yaşıyorum.Basit bir Gradient Descent algoritması nasıl oluşturulur

Oturma bölümü (feet2: Burada

ben yeniden oluşturmaya çalışıyorum örnektir, ben çıkan fiyatıyla (feet2 yaşayan alanına() ve yatak odası sayısı) ile evlerin hakkında veri var): 2104

#bedrooms: 3

Fiyatı (1000 $ ler): 400

Ben dik iniş metodunu kullanarak basit bir regresyon yapmaya çalışıyorum, ancak benim algoritma çalışmaz. .. Algoritmanın şekli usi değildir. ng vektörleri amaca göre (adım adım anlamaya çalışıyorum).

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 

ben $x_1$ http://mathurl.com/2ga69bb.png ve $x_2$ http://mathurl.com/2cbdldp.png ve $h_{\theta}(x)$ http://mathurl.com/jckw8ke.png tahmini fiyatı (alanı, yatak odası sayısını yaşayan) değişkenleri olmak öngörücü bir fonksiyonu $$h_{\theta}(x) = \theta_0 + \theta_1 x_1 + \theta_2 x_2$$ http://mathurl.com/hoy7ege.png inşa ediyorum, matematik anlıyoruz. , $$hserror = \frac{1}{2} (h_{\theta}(x) - y)^2$$ http://mathurl.com/hnrqtkf.png Bu olağan bir sorundur, ancak bir yazılım mühendisi daha ve ben her seferinde bir adım öğreniyorum edebilirsiniz:

Ben (bir nokta için) maliyet fonksiyonunu ($hserror$ http://mathurl.com/guuqjv5.png) kullanıyorum bana neyin yanlış olduğunu söyle

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) 

böyle cevapları ile biter:

Ben bu kodla çalışma var

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 

cevap

8

İlk sayı verilerin sadece tek parça ile bu çalışan size gereğinden az sağlamasıdır sistem ... bu sonsuz sayıda çözümlere sahip olabileceği anlamına gelir. Üç değişkenle, tercihen en fazla 3 veri noktasının olmasını beklersiniz. İkinci adımda, gradyanın ölçekli bir versiyonunun olduğu gradyan alçalmasının, çözümün küçük bir mahallesi dışında, yakınsama garantisi olmadığı kanaatine varılmıştır. Bunu, negatif degrade (yavaş) veya negatif degrade (daha hızlı, ancak biraz daha karmaşık) yönündeki bir satır aralığına sabit bir boyut adımına geçerek (daha hızlı, ancak biraz daha karmaşık)

theta0 = theta0 - step * dEdtheta0 
theta1 = theta1 - step * dEdtheta1 
theta2 = theta2 - step * dEdtheta2 

ait size adımda bir işaret hata olabilir gibi bu

n = max([ dEdtheta1, dEdtheta1, dEdtheta2 ])  
theta0 = theta0 - step * dEdtheta0/n 
theta1 = theta1 - step * dEdtheta1/n 
theta2 = theta2 - step * dEdtheta2/n 

Ayrıca görünüyor yapmak.

Ayrıca derror'un iyi bir durdurma kriteri olduğundan emin değilim. (Ancak "durdurma" kriterleri, "doğru" almak için çok zorlanıyor)

Son nokta, gradyan inişin parametre uyumu için aşırı derecede yavaş olmasıdır. Muhtemelen konjugat gradyanını veya Levenberg-Marquadt yöntemlerini kullanmak istersiniz.Ben bu yöntemlerin her ikisi de zaten plikhon için python için mevcut olduğunu varsayıyoruz (varsayılan olarak pythonun bir parçası değildir, ancak kurulumu oldukça kolaydır)

+0

Harika cevabınız için teşekkür ederiz! Bu sorunun büyük bir yaklaşımı olmadığını biliyorum, önce bu basit çözümü uygulamayı denemek istedim ve daha sonra değişken bir adımı kullanmak ve hem "toplu gradyan inişi" hem de "stokastik degrade iniş" denemek istedim. –

+0

Sadece dEdtheta için kullandığınız ifadenin ne olduğundan emin olmak için? –

+0

d = 400 - theta0 - 2104 * theta1 - 3 * theta2, E = d^2, dEdtheta0 = 2 * d * (-1), dEdtheta1 = 2 * d * (-2104), dEdtheta2 = 2 * d * (- 3). Bu, orijinal denklemlerdeki işareti doğru yapar. Fakat eğer gradyanların büyüklüğüne bakarsanız, 0.0001 ölçek faktörüne kıyasla çok büyüktür, bu da başlangıç ​​noktanızdan çok büyük olan adım boyutlarını almanız anlamına gelir. Degradeyi normalleştirme veya adım tarafını başka bir şekilde sınırlama, sorununuzu çözmelidir. –

İlgili konular