21

Tôi cố gắng để thực hiện thuật toán này để tìm tung độ gốc và độ dốc cho biến duy nhất:Simple Linear Regression bằng Python

ALGORITHM OF THE LINEAR REGRESSION

Đây là mã Python của tôi để cập nhật các Intercept và dốc. Nhưng nó không hội tụ. RSS đang tăng với Iteration thay vì giảm và sau một số lần lặp lại nó trở thành vô hạn. Tôi không tìm thấy bất kỳ lỗi nào khi triển khai thuật toán. Tôi có thể giải quyết vấn đề này như thế nào? Tôi đã đính kèm tệp csv. Đây là mã.

import pandas as pd 
import numpy as np 

#Defining gradient_decend 
#This Function takes X value, Y value and vector of w0(intercept),w1(slope) 
#INPUT FEATURES=X(sq.feet of house size) 
#TARGET VALUE=Y (Price of House) 
#W=np.array([w0,w1]).reshape(2,1) 
#W=[w0, 
# w1] 

def gradient_decend(X,Y,W): 
    intercept=W[0][0] 
    slope=W[1][0] 

    #Here i will get a list 
    #list is like this 
    #gd=[sum(predicted_value-(intercept+slope*x)), 
    #  sum(predicted_value-(intercept+slope*x)*x)] 
    gd=[sum(y-(intercept+slope*x) for x,y in zip(X,Y)), 
     sum(((y-(intercept+slope*x))*x) for x,y in zip(X,Y))] 
    return np.array(gd).reshape(2,1) 

#Defining Resudual sum of squares 
def RSS(X,Y,W): 
    return sum((y-(W[0][0]+W[1][0]*x))**2 for x,y in zip(X,Y)) 


#Reading Training Data 
training_data=pd.read_csv("kc_house_train_data.csv") 

#Defining fixed parameters 
#Learning Rate 
n=0.0001 
iteration=1500 
#Intercept 
w0=0 
#Slope 
w1=0 

#Creating 2,1 vector of w0,w1 parameters 
W=np.array([w0,w1]).reshape(2,1) 

#Running gradient Decend 
for i in range(iteration): 
    W=W+((2*n)* (gradient_decend(training_data["sqft_living"],training_data["price"],W))) 
    print RSS(training_data["sqft_living"],training_data["price"],W) 

Here là tệp CSV.

+0

; P đó là từ Đại học Washington lớp máy leanring, tôi lấy nó quá, nó đã rất vui vẻ và làm sáng tỏ. Tôi đề nghị bạn sử dụng diễn đàn trên coursera và bạn có thể nhận được câu trả lời rất tốt từ các cố vấn, tình nguyện viên và sinh viên. https://www.coursera.org/learn/ml-regression/discussions – alvas

Trả lời

3

tôi đã giải quyết được vấn đề của riêng tôi!

Đây là cách được giải quyết.

import numpy as np 
import pandas as pd 
import math 
from sys import stdout 

#function Takes the pandas dataframe, Input features list and the target column name 
def get_numpy_data(data, features, output): 

    #Adding a constant column with value 1 in the dataframe. 
    data['constant'] = 1  
    #Adding the name of the constant column in the feature list. 
    features = ['constant'] + features 
    #Creating Feature matrix(Selecting columns and converting to matrix). 
    features_matrix=data[features].as_matrix() 
    #Target column is converted to the numpy array 
    output_array=np.array(data[output]) 
    return(features_matrix, output_array) 

def predict_outcome(feature_matrix, weights): 
    weights=np.array(weights) 
    predictions = np.dot(feature_matrix, weights) 
    return predictions 

def errors(output,predictions): 
    errors=predictions-output 
    return errors 

def feature_derivative(errors, feature): 
    derivative=np.dot(2,np.dot(feature,errors)) 
    return derivative 


def regression_gradient_descent(feature_matrix, output, initial_weights, step_size, tolerance): 
    converged = False 
    #Initital weights are converted to numpy array 
    weights = np.array(initial_weights) 
    while not converged: 
     # compute the predictions based on feature_matrix and weights: 
     predictions=predict_outcome(feature_matrix,weights) 
     # compute the errors as predictions - output: 
     error=errors(output,predictions) 
     gradient_sum_squares = 0 # initialize the gradient 
     # while not converged, update each weight individually: 
     for i in range(len(weights)): 
      # Recall that feature_matrix[:, i] is the feature column associated with weights[i] 
      feature=feature_matrix[:, i] 
      # compute the derivative for weight[i]: 
      #predict=predict_outcome(feature,weights[i]) 
      #err=errors(output,predict) 
      deriv=feature_derivative(error,feature) 
      # add the squared derivative to the gradient magnitude 
      gradient_sum_squares=gradient_sum_squares+(deriv**2) 
      # update the weight based on step size and derivative: 
      weights[i]=weights[i] - np.dot(step_size,deriv) 

     gradient_magnitude = math.sqrt(gradient_sum_squares) 
     stdout.write("\r%d" % int(gradient_magnitude)) 
     stdout.flush() 
     if gradient_magnitude < tolerance: 
      converged = True 
    return(weights) 


#Example of Implementation 
#Importing Training and Testing Data 
# train_data=pd.read_csv("kc_house_train_data.csv") 
# test_data=pd.read_csv("kc_house_test_data.csv") 

# simple_features = ['sqft_living', 'sqft_living15'] 
# my_output= 'price' 
# (simple_feature_matrix, output) = get_numpy_data(train_data, simple_features, my_output) 
# initial_weights = np.array([-100000., 1., 1.]) 
# step_size = 7e-12 
# tolerance = 2.5e7 
# simple_weights = regression_gradient_descent(simple_feature_matrix, output,initial_weights, step_size,tolerance) 
# print simple_weights 
9

Đầu tiên, tôi thấy rằng khi viết mã học máy, tốt nhất là KHÔNG để sử dụng danh sách phức tạp hiểu vì bất cứ điều gì mà bạn có thể lặp lại,

  • nó dễ dàng hơn để đọc nếu bằng văn bản khi vòng bình thường và thụt đầu dòng và/hoặc
  • nó có thể được thực hiện với numpy broadcasting

Và sử dụng tên biến thích hợp có thể giúp bạn hiểu rõ hơn về các mã. Sử dụng Xs, Ys, Ws làm bàn tay ngắn chỉ tốt nếu bạn giỏi môn toán. Cá nhân, tôi không sử dụng chúng trong mã, đặc biệt là khi viết bằng python. Từ import this: rõ ràng là tốt hơn so với ngụ ý.

Quy tắc chung của tôi là hãy nhớ rằng nếu tôi viết mã, tôi không thể đọc 1 tuần sau, đó là mã không hợp lệ.


Trước tiên, hãy quyết định các thông số đầu vào cho gradient descent là gì, bạn sẽ cần:

  • feature_matrix (The X ma trận, gõ: numpy.array, một ma trận của N kích thước * D, trong đó N là số của các hàng/datapoints và D là số cột/tính năng)
  • đầu ra (Y vector, loại: numpy.array, vectơ có kích thước N)
  • initial_weights (loại: numpy.array, vectơ có kích thước D).

Bên cạnh đó, để kiểm tra tụ, bạn sẽ cần:

  • step_size (tầm quan trọng của sự thay đổi khi iterating qua để thay đổi trọng lượng; loại: float, thường là một số nhỏ)
  • khoan dung (các tiêu chí để phá vỡ sự lặp đi lặp lại, khi cường độ dốc nhỏ hơn khoan dung, cho rằng trọng lượng của bạn đã convereged, gõ: float, thường là một số nhỏ nhưng lớn hơn nhiều so với st kích thước ep).

Bây giờ đến mã.

def regression_gradient_descent(feature_matrix, output, initial_weights, step_size, tolerance): 
    converged = False # Set a boolean to check for convergence 
    weights = np.array(initial_weights) # make sure it's a numpy array 

    while not converged: 
     # compute the predictions based on feature_matrix and weights. 
     # iterate through the row and find the single scalar predicted 
     # value for each weight * column. 
     # hint: a dot product can solve this easily 
     predictions = [??? for row in feature_matrix] 
     # compute the errors as predictions - output 
     errors = predictions - output 
     gradient_sum_squares = 0 # initialize the gradient sum of squares 
     # while we haven't reached the tolerance yet, update each feature's weight 
     for i in range(len(weights)): # loop over each weight 
      # Recall that feature_matrix[:, i] is the feature column associated with weights[i] 
      # compute the derivative for weight[i]: 
      # Hint: the derivative is = 2 * dot product of feature_column and errors. 
      derivative = 2 * ???? 
      # add the squared value of the derivative to the gradient magnitude (for assessing convergence) 
      gradient_sum_squares += (derivative * derivative) 
      # subtract the step size times the derivative from the current weight 
      weights[i] -= (step_size * derivative) 

     # compute the square-root of the gradient sum of squares to get the gradient magnitude: 
     gradient_magnitude = ??? 
     # Then check whether the magnitude is lower than the tolerance. 
     if ???: 
      converged = True 
    # Once it while loop breaks, return the loop. 
    return(weights) 

Tôi hy vọng mã mở rộng giúp bạn hiểu rõ hơn về độ dốc. Tôi sẽ không điền vào số ??? để không làm hỏng bài tập về nhà của bạn.


Lưu ý rằng mã RSS của bạn cũng không đọc được và không thể đọc được. Nó dễ dàng hơn để làm:

>>> import numpy as np 
>>> prediction = np.array([1,2,3]) 
>>> output = np.array([1,1,5]) 
>>> residual = output - prediction 
>>> RSS = sum(residual * residual) 
>>> RSS 
5 

Đi qua căn bản numpy sẽ đi một chặng đường dài để học máy và ma trận vector thao tác mà không đi các loại hạt với lặp: http://docs.scipy.org/doc/numpy-1.10.1/user/basics.html

+0

Bạn có thể dễ dàng thay đổi mã dung sai thành không. của vòng lặp (cho vòng lặp), chỉ cần thay đổi cách bạn kiểm soát vòng lặp bên ngoài. Nhưng ưu tiên của tôi là để đi cho hội tụ khoan dung (trong khi vòng lặp). – alvas

0

Nó là đơn giản như vậy

def mean(values): 
    return sum(values)/float(len(values)) 

def variance(values, mean): 
    return sum([(x-mean)**2 for x in values]) 

def covariance(x, mean_x, y, mean_y): 
    covar = 0.0 
    for i in range(len(x)): 
     covar+=(x[i]-mean_x) * (y[i]-mean_y) 
    return covar 
def coefficients(dataset): 
    x = [] 
    y = [] 

    for line in dataset: 
     xi, yi = map(float, line.split(',')) 

     x.append(xi) 
     y.append(yi) 

    dataset.close()        

    x_mean, y_mean = mean(x), mean(y) 

    b1 = covariance(x, x_mean, y, y_mean)/variance(x, x_mean) 
    b0 = y_mean-b1*x_mean 

    return [b0, b1] 

dataset = open('trainingdata.txt') 

b0, b1 = coefficients(dataset) 

n=float(raw_input()) 

print(b0+b1*n) 

tham khảo: www.machinelearningmastery.com/implement-simple-linear-regression-scratch-python/