it-swarm.com.de

Einfache lineare Regression in Python

Ich versuche diesen Algorithmus zu implementieren, um den Schnittpunkt und die Steigung für einzelne Variablen zu finden:

 ALGORITHM OF THE LINEAR REGRESSION

Hier ist mein Python-Code, um den Intercept und die Steigung zu aktualisieren. Aber es ist nicht konvergierend. RSS nimmt mit der Iteration zu, anstatt abzunehmen, und nach einer Iteration wird es unendlich. Ich finde keinen Fehler beim Implementieren des Algorithmus. Wie kann ich dieses Problem lösen? Ich habe auch die CSV-Datei angehängt. Hier ist der Code.

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)

Hier ist die CSV-Datei.

Ich habe mein eigenes Problem gelöst!

Hier ist der gelöste Weg.

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

Erstens finde ich, dass es beim Schreiben von maschinellem Lerncode am besten ist,NICHTdas komplexe Listenverständnis zu verwenden, da alles, was Sie iterieren können, 

  • es ist einfacher zu lesen, wenn es geschrieben wird, wenn normale Schleifen und Einrückungen und/oder 
  • es kann mit numpy Broadcasting gemacht werden

Durch die Verwendung der richtigen Variablennamen können Sie den Code besser verstehen. Die Verwendung von Xs, Ys, Ws als kurze Hand ist nur dann Nizza, wenn Sie mit Mathematik umgehen können. Ich persönlich benutze sie nicht im Code, besonders wenn ich in Python schreibe. Aus import this: explizit ist besser als implizit.

Meine Faustregel ist, daran zu denken, dass ich, wenn ich Code schreibe, die ich nicht 1 Woche später lesen kann, fehlerhafter Code ist. 


Lassen Sie uns zunächst entscheiden, welche Eingabeparameter für den Gradientenabstieg erforderlich sind:

  • feature_matrix (In die X-Matrix geben Sie Folgendes ein: numpy.array, eine Matrix der Größe N * D, wobei N die Anzahl der Zeilen/Datenpunkte und D die Anzahl der Spalten/Features ist.)
  • output (Der Y-Vektor, Typ: numpy.array, ein Vektor der Größe N)
  • Anfangsgewichte (Typ: numpy.array, ein Vektor der Größe D).

Um die Konvergenz zu überprüfen, benötigen Sie zusätzlich:

  • step_size (die Größe der Änderung beim Durchlaufen der Gewichtung; durch Eingabe von float, normalerweise eine kleine Zahl)
  • toleranz (Die Kriterien zum Durchbrechen der Iterationen, wenn der Gradientenbetrag kleiner als die Toleranz ist, setzen voraus, dass Ihre Gewichte konvexiert wurden. Geben Sie Folgendes ein: float, normalerweise eine kleine Zahl, jedoch viel größer als die Schrittgröße).

Nun zum Code.

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)

Ich hoffe, der erweiterte Pseudocode hilft Ihnen, den Gradientenabstieg besser zu verstehen. Ich werde nicht den ??? eingeben, um Ihre Hausaufgaben nicht zu verderben.


Beachten Sie, dass Ihr RSS-Code auch nicht lesbar und nicht pflegbar ist. Es ist einfacher, nur zu tun: 

>>> 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

Das Durchlaufen der numpy-Grundlagen führt zu maschinellem Lernen und Matrix-Vektor-Manipulation, ohne mit Iterationen verrückt zu werden: http://docs.scipy.org/doc/numpy-1.10.1/user/basics.html

9
alvas

Es ist so einfach

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)

referenz: www.machinelearningmastery.com/implement-simple-linear-regression-scratch-python/

0
Aslam Shaik