2010-10-01 42 views
7

Tôi đang nghiên cứu các thuật toán học máy đơn giản, bắt đầu với một gốc dốc đơn giản, nhưng tôi đã gặp một số sự cố khi cố triển khai nó trong python.Cách tạo một thuật toán Gradient Descent đơn giản

Dưới đây là ví dụ tôi đang cố gắng để tái sản xuất, tôi đã có dữ liệu về nhà với (khu vực sống (trong feet2), và số lượng phòng ngủ) với giá kết quả:

khu vực sinh hoạt chung (feet2): 2104

#bedrooms: 3

Giá (1000 $ s): 400

tôi đang cố gắng để làm một hồi quy đơn giản bằng cách sử dụng phương pháp gradient descent, nhưng thuật toán của tôi sẽ không làm việc. .. Hình thức của thuật toán không phải là usi ng vectơ về mục đích (Tôi đang cố gắng để hiểu nó từng bước).

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 

Tôi hiểu toán học, Tôi đang xây dựng một chức năng tiên đoán $$h_{\theta}(x) = \theta_0 + \theta_1 x_1 + \theta_2 x_2$$ http://mathurl.com/hoy7ege.png với $x_1$ http://mathurl.com/2ga69bb.png$x_2$ http://mathurl.com/2cbdldp.png là các biến và $h_{\theta}(x)$ http://mathurl.com/jckw8ke.png giá ước tính (diện tích, số phòng ngủ sống).

Tôi đang sử dụng hàm chi phí ($hserror$ http://mathurl.com/guuqjv5.png) (đối với một điểm): $$hserror = \frac{1}{2} (h_{\theta}(x) - y)^2$$ http://mathurl.com/hnrqtkf.png Đây là vấn đề thường lệ, nhưng tôi nhiều hơn một kỹ sư phần mềm và tôi đang học thêm một bước tại một thời điểm, có thể bạn nói cho tôi biết có chuyện gì không?

tôi nhận nó làm việc với mã này:

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) 

mà kết thúc với câu trả lời như thế này:

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 

Trả lời

8

vấn đề đầu tiên là chạy này với chỉ một phần dữ liệu cung cấp cho bạn một underdetermined hệ thống ... điều này có nghĩa là nó có thể có vô số các giải pháp. Với ba biến, bạn mong muốn có ít nhất 3 điểm dữ liệu, tốt nhất là cao hơn nhiều.

Thứ hai sử dụng độ dốc gốc khi kích thước bước là phiên bản được chia tỷ lệ của độ dốc không được đảm bảo để hội tụ ngoại trừ trong một vùng lân cận nhỏ của giải pháp. Bạn có thể khắc phục điều đó bằng cách chuyển sang bước kích thước cố định theo hướng của gradient âm (chậm) hoặc tìm kiếm theo hướng của độ dốc âm (nhanh hơn nhưng hơi phức tạp hơn)

Vì vậy, đối với kích thước bước cố định của

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

bạn làm điều này

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

Nó cũng có vẻ như bạn có thể có một lỗi đăng nhập các bước của bạn.

Tôi cũng không chắc chắn rằng derror là tiêu chí dừng tốt. (Tuy nhiên, tiêu chí dừng lại nổi tiếng là khó có được "đúng")

Điểm cuối cùng của tôi là điểm gốc dốc là chậm chạp để lắp đặt thông số. Bạn có thể muốn sử dụng phương pháp liên hợp-gradient hoặc Levenberg-Marquadt thay thế.Tôi nghi ngờ rằng cả hai phương pháp này đã tồn tại cho python trong các gói gọn gàng hoặc scipy (không phải là một phần của python theo mặc định nhưng khá dễ cài đặt)

+0

Cảm ơn câu trả lời tuyệt vời của bạn! tôi biết rằng nó không phải là một cách tiếp cận tuyệt vời của vấn đề, tôi muốn thử thực hiện giải pháp này đơn giản đầu tiên và sau đó sử dụng một bước biến và thử cả "batch gradient descent" và "stochastic gradient descent". –

+0

Chỉ để chắc chắn biểu thức bạn sử dụng cho dEdtheta là gì? –

+0

Tôi muốn lấy d = 400 - theta0 - 2104 * theta1 - 3 * theta2, E = d^2, dEdtheta0 = 2 * d * (-1), dEdtheta1 = 2 * d * (-2104), dEdtheta2 = 2 * d * (- 3). Mà sẽ làm cho các dấu hiệu trong phương trình ban đầu của bạn chính xác. Nhưng nếu bạn nhìn vào kích thước của các gradient, chúng rất lớn so với hệ số thang đo 0,0001, điều đó có nghĩa là bạn đã kết thúc các kích thước bước quá lớn so với điểm bắt đầu của bạn. Bình thường hóa gradient, hoặc hạn chế phía bước theo một cách khác, nên giải quyết vấn đề của bạn. –

Các vấn đề liên quan