2010-10-01 18 views
7

कैसे बनाएं मैं सरल मशीन सीखने वाले एल्गोरिदम का अध्ययन कर रहा हूं, जो एक साधारण ढाल वाले वंश से शुरू होता है, लेकिन मुझे इसे अजगर में लागू करने में कुछ परेशानी हो रही है।एक साधारण ग्रेडियेंट वंश एल्गोरिदम

बैठक क्षेत्र (feet2:

यहाँ उदाहरण मैं पुन: पेश करने की कोशिश कर रहा हूँ है, मैं ((रहने वाले क्षेत्र feet2 में), और बेडरूम की संख्या) जिसके परिणामस्वरूप मूल्य के साथ साथ घरों के बारे में डेटा मिल गया है): 2104

#bedrooms: 3

मूल्य ($ 1000 रों): 400

मैं ढाल वंश विधि का उपयोग कर एक सरल प्रतिगमन करने के लिए कोशिश कर रहा हूँ, लेकिन मेरे एल्गोरिथ्म काम नहीं करेगा। .. एल्गोरिदम का रूप usi नहीं है उद्देश्य पर एनजी वैक्टर (मैं इसे चरण-दर-चरण समझने की कोशिश कर रहा हूं)।

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 

मैं गणित समझते हैं, मैं $x_1$ http://mathurl.com/2ga69bb.png और $x_2$ http://mathurl.com/2cbdldp.png जा रहा है चर (रहने वाले क्षेत्र, बेडरूम की संख्या) और $h_{\theta}(x)$ http://mathurl.com/jckw8ke.png अनुमानित कीमत के साथ एक भविष्यवाणी समारोह $$h_{\theta}(x) = \theta_0 + \theta_1 x_1 + \theta_2 x_2$$ http://mathurl.com/hoy7ege.png निर्माण कर रहा हूँ। $$hserror = \frac{1}{2} (h_{\theta}(x) - y)^2$$ http://mathurl.com/hnrqtkf.png यह एक सामान्य समस्या है, लेकिन मैं एक सॉफ्टवेयर इंजीनियर के और अधिक कर रहा हूँ और मैं एक समय में एक कदम सीख रहा हूँ कर सकते हैं,:

मैं लागत समारोह ($hserror$ http://mathurl.com/guuqjv5.png) (एक बिंदु के लिए) का उपयोग कर रहा तुम मुझे बताओ क्या गलत है?

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) 

जो इस तरह जवाब के साथ समाप्त होता है:

मैं इसे इस कोड के साथ काम कर ली

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 

उत्तर

8

प्रथम मुद्दा यह है कि डेटा का केवल एक टुकड़ा के साथ इस चल आप एक underdetermined देता है सिस्टम ... इसका मतलब है कि इसमें असीमित समाधान हो सकते हैं। तीन चर के साथ, आप अपेक्षाकृत कम से कम 3 डेटा अंक होने की उम्मीद करेंगे, अधिमानतः बहुत अधिक।

दूसरा ग्रेडिएंट वंश का उपयोग करते हुए जहां चरण आकार ग्रेडियेंट का एक स्केल संस्करण है, समाधान के एक छोटे पड़ोस को छोड़कर अभिसरण करने की गारंटी नहीं है। आप ऋणात्मक ढाल (धीमी) की दिशा में एक निश्चित आकार चरण या नकारात्मक ढाल (तेज, लेकिन थोड़ा अधिक जटिल) की दिशा में एक निश्चित आकार चरण में स्विच करके इसे ठीक कर सकते हैं

तो इसके बजाय निश्चित चरण आकार के लिए

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

की आप इस

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

यह भी लगता है कि आप अपने चरणों में एक संकेत त्रुटि हो करो।

मुझे यह भी यकीन नहीं है कि आतंक एक अच्छा रोक मानदंड है। (लेकिन मानदंडों को रोकना "सही" पाने के लिए कुख्यात रूप से कठिन है)

मेरा अंतिम बिंदु यह है कि ग्रेडियेंट वंश पैरामीटर फिटिंग के लिए बहुत धीमी है। आप शायद इसके बजाय conjugate-gradient या Levenberg-Marquadt विधियों का उपयोग करना चाहते हैं।मुझे संदेह है कि इन दोनों विधियों में पहले से ही पाइथन के लिए मौजूद है या नुकीले पैकेजों (जो डिफ़ॉल्ट रूप से पायथन का हिस्सा नहीं हैं लेकिन स्थापित करने में बहुत आसान हैं)

+0

आपके महान उत्तर के लिए धन्यवाद! मुझे पता है कि यह समस्या का एक बड़ा दृष्टिकोण नहीं है, मैं पहले इस सरल समाधान को लागू करने की कोशिश करना चाहता था और फिर एक परिवर्तनीय चरण का उपयोग करना चाहता था और "बैच ग्रेडियेंट वंश" और "स्टोकास्टिक ग्रेडेंट वंश" दोनों को आजमाएं। –

+0

बस यह सुनिश्चित करने के लिए कि आप अभिव्यक्ति के लिए उपयोग की जाने वाली अभिव्यक्ति क्या है? –

+0

मैं डी = 400 लेता हूं - theta0 - 2104 * theta1 - 3 * theta2, ई = डी^2, dEdtheta0 = 2 * डी * (-1), dEdtheta1 = 2 * डी * (-2104), dEdtheta2 = 2 * घ * (- 3)। जो आपके मूल समीकरणों में सही संकेत देगा। लेकिन यदि आप ग्रेडियेंट्स के आकार को देखते हैं, तो वे 0.0001 स्केल फैक्टर की तुलना में बहुत अधिक हैं, जिसका अर्थ है कि आप अपने शुरुआती बिंदु से बहुत बड़े आकार के कदम लेते हैं। ढाल को सामान्यीकृत करना, या किसी अन्य तरीके से चरण पक्ष को सीमित करना, आपकी समस्या को हल करना चाहिए। –

संबंधित मुद्दे