it-swarm.com.de

gradientenabstieg mit Python und Numpy

def gradient(X_norm,y,theta,alpha,m,n,num_it):
    temp=np.array(np.zeros_like(theta,float))
    for i in range(0,num_it):
        h=np.dot(X_norm,theta)
        #temp[j]=theta[j]-(alpha/m)*(  np.sum( (h-y)*X_norm[:,j][np.newaxis,:] )  )
        temp[0]=theta[0]-(alpha/m)*(np.sum(h-y))
        temp[1]=theta[1]-(alpha/m)*(np.sum((h-y)*X_norm[:,1]))
        theta=temp
    return theta



X_norm,mean,std=featureScale(X)
#length of X (number of rows)
m=len(X)
X_norm=np.array([np.ones(m),X_norm])
n,m=np.shape(X_norm)
num_it=1500
alpha=0.01
theta=np.zeros(n,float)[:,np.newaxis]
X_norm=X_norm.transpose()
theta=gradient(X_norm,y,theta,alpha,m,n,num_it)
print theta

Mein Theta aus dem obigen Code ist 100.2 100.2, aber es sollte 100.2 61.09 in matlab sein, was korrekt ist.

53
Madan Ram

Ich denke, Ihr Code ist ein bisschen zu kompliziert und erfordert mehr Struktur, da Sie sonst in allen Gleichungen und Operationen verloren gehen. Am Ende läuft diese Regression auf vier Operationen zurück:

  1. Berechnen Sie die Hypothese h = X * theta
  2. Berechnen Sie den Verlust = h - y und möglicherweise die quadrierten Kosten (Verlust ^ 2)/2m
  3. Berechnen Sie den Gradienten = X '* Verlust/m
  4. Aktualisieren Sie die Parameter theta = theta - alpha * gradient

In Ihrem Fall haben Sie wahrscheinlich m mit n verwechselt. m gibt hier die Anzahl der Beispiele in Ihrem Trainingssatz an, nicht die Anzahl der Features.

Schauen wir uns meine Variation Ihres Codes an:

import numpy as np
import random

# m denotes the number of examples here, not the number of features
def gradientDescent(x, y, theta, alpha, m, numIterations):
    xTrans = x.transpose()
    for i in range(0, numIterations):
        hypothesis = np.dot(x, theta)
        loss = hypothesis - y
        # avg cost per example (the 2 in 2*m doesn't really matter here.
        # But to be consistent with the gradient, I include it)
        cost = np.sum(loss ** 2) / (2 * m)
        print("Iteration %d | Cost: %f" % (i, cost))
        # avg gradient per example
        gradient = np.dot(xTrans, loss) / m
        # update
        theta = theta - alpha * gradient
    return theta


def genData(numPoints, bias, variance):
    x = np.zeros(shape=(numPoints, 2))
    y = np.zeros(shape=numPoints)
    # basically a straight line
    for i in range(0, numPoints):
        # bias feature
        x[i][0] = 1
        x[i][1] = i
        # our target variable
        y[i] = (i + bias) + random.uniform(0, 1) * variance
    return x, y

# gen 100 points with a bias of 25 and 10 variance as a bit of noise
x, y = genData(100, 25, 10)
m, n = np.shape(x)
numIterations= 100000
alpha = 0.0005
theta = np.ones(n)
theta = gradientDescent(x, y, theta, alpha, m, numIterations)
print(theta)

Zuerst erstelle ich einen kleinen zufälligen Datensatz, der folgendermaßen aussehen sollte:

Linear Regression

Wie Sie sehen, habe ich auch die generierte Regressionslinie und Formel hinzugefügt, die von Excel berechnet wurde.

Sie müssen auf die Intuition der Regression mit Gradientenabstieg achten. Wenn Sie eine vollständige Stapelübergabe über Ihre Daten X durchführen, müssen Sie die m-Verluste jedes Beispiels auf eine einzige Gewichtsaktualisierung reduzieren. In diesem Fall ist dies der Durchschnitt der Summe über die Gradienten, also die Division durch m

Als nächstes müssen Sie die Konvergenz verfolgen und die Lernrate anpassen. In diesem Zusammenhang sollten Sie Ihre Kosten immer bei jeder Wiederholung nachverfolgen, vielleicht sogar planen.

Wenn Sie mein Beispiel ausführen, sieht das zurückgegebene Theta folgendermaßen aus:

Iteration 99997 | Cost: 47883.706462
Iteration 99998 | Cost: 47883.706462
Iteration 99999 | Cost: 47883.706462
[ 29.25567368   1.01108458]

Das ist ziemlich nahe an der von Excel berechneten Gleichung (y = x + 30). Wenn wir die Vorspannung in die erste Spalte übergeben haben, gibt der erste Theta-Wert das Vorspannungsgewicht an.

119
Thomas Jungblut

Im Folgenden finden Sie meine Implementierung des Gradientenabfalls für das lineare Regressionsproblem. 

Zuerst berechnen Sie den Gradienten wie X.T * (X * w - y) / N und aktualisieren gleichzeitig Ihren aktuellen Theta mit diesem Gradienten. 

  • X: Merkmalsmatrix 
  • y: Zielwerte 
  • w: Gewichte/Werte 
  • N: Größe des Trainingssatzes

Hier ist der Python-Code:

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import random

def generateSample(N, variance=100):
    X = np.matrix(range(N)).T + 1
    Y = np.matrix([random.random() * variance + i * 10 + 900 for i in range(len(X))]).T
    return X, Y

def fitModel_gradient(x, y):
    N = len(x)
    w = np.zeros((x.shape[1], 1))
    eta = 0.0001

    maxIteration = 100000
    for i in range(maxIteration):
        error = x * w - y
        gradient = x.T * error / N
        w = w - eta * gradient
    return w

def plotModel(x, y, w):
    plt.plot(x[:,1], y, "x")
    plt.plot(x[:,1], x * w, "r-")
    plt.show()

def test(N, variance, modelFunction):
    X, Y = generateSample(N, variance)
    X = np.hstack([np.matrix(np.ones(len(X))).T, X])
    w = modelFunction(X, Y)
    plotModel(X, Y, w)


test(50, 600, fitModel_gradient)
test(50, 1000, fitModel_gradient)
test(100, 200, fitModel_gradient)

 test1  test2  test2

10
Muatik

Ich weiß, dass diese Frage bereits beantwortet wurde, aber ich habe einige Änderungen an der Gd-Funktion vorgenommen:

  ### COST FUNCTION

def cost(theta,X,y):
     ### Evaluate half MSE (Mean square error)
     m = len(y)
     error = np.dot(X,theta) - y
     J = np.sum(error ** 2)/(2*m)
     return J

 cost(theta,X,y)



def Gd(X,y,theta,alpha):

    cost_histo = [0]
    theta_histo = [0]

    # an arbitrary gradient, to pass the initial while() check
    delta = [np.repeat(1,len(X))]
    # Initial theta
    old_cost = cost(theta,X,y)

    while (np.max(np.abs(delta)) > 1e-6):
        error = np.dot(X,theta) - y
        delta = np.dot(np.transpose(X),error)/len(y)
        trial_theta = theta - alpha * delta
        trial_cost = cost(trial_theta,X,y)
        while (trial_cost >= old_cost):
            trial_theta = (theta +trial_theta)/2
            trial_cost = cost(trial_theta,X,y)
            cost_histo = cost_histo + trial_cost
            theta_histo = theta_histo +  trial_theta
        old_cost = trial_cost
        theta = trial_theta
    Intercept = theta[0] 
    Slope = theta[1]  
    return [Intercept,Slope]

res = Gd(X,y,theta,alpha)

Diese Funktion verringert den Alphawert während der Iteration, wodurch die Funktion zu schneller konvergiert wird. Siehe Lineare Regression mit Gradientabstieg (steilster Abstieg) schätzen Für ein Beispiel in R benutze ich dieselbe Logik, aber in Python.

2
Nico Coallier

Nach der Implementierung von @ thomas-jungblut in Python habe ich das auch für Octave getan. Wenn Sie etwas falsch finden, lassen Sie es mich wissen und ich werde das Update korrigieren.

Die Daten stammen aus einer Textdatei mit den folgenden Zeilen:

1 10 1000
2 20 2500
3 25 3500
4 40 5500
5 60 6200

betrachten Sie es als eine sehr grobe Probe für die Merkmale [Anzahl der Schlafzimmer] [mts2] und die letzte Spalte [Mietpreis], die wir vorhersagen möchten.

Hier ist die Octave-Implementierung:

%
% Linear Regression with multiple variables
%

% Alpha for learning curve
alphaNum = 0.0005;

% Number of features
n = 2;

% Number of iterations for Gradient Descent algorithm
iterations = 10000

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% No need to update after here
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

DATA = load('CHANGE_WITH_DATA_FILE_PATH');

% Initial theta values
theta = ones(n + 1, 1);

% Number of training samples
m = length(DATA(:, 1));

% X with one mor column (x0 filled with '1's)
X = ones(m, 1);
for i = 1:n
  X = [X, DATA(:,i)];
endfor

% Expected data must go always in the last column  
y = DATA(:, n + 1)

function gradientDescent(x, y, theta, alphaNum, iterations)
  iterations = [];
  costs = [];

  m = length(y);

  for iteration = 1:10000
    hypothesis = x * theta;

    loss = hypothesis - y;

    % J(theta)    
    cost = sum(loss.^2) / (2 * m);

    % Save for the graphic to see if the algorithm did work
    iterations = [iterations, iteration];
    costs = [costs, cost];

    gradient = (x' * loss) / m; % /m is for the average

    theta = theta - (alphaNum * gradient);
  endfor    

  % Show final theta values
  display(theta)

  % Show J(theta) graphic evolution to check it worked, tendency must be zero
  plot(iterations, costs);

endfunction

% Execute gradient descent
gradientDescent(X, y, theta, alphaNum, iterations);
0