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
Mon thêta du code ci-dessus est 100.2 100.2
, mais il devrait être 100.2 61.09
dans matlab qui est correct.
Je pense que votre code est un peu trop compliqué et qu'il a besoin de plus de structure, car sinon vous serez perdu dans toutes les équations et opérations. En fin de compte, cette régression se résume à quatre opérations:
Dans votre cas, je suppose que vous avez confondu m
avec n
. Ici m
indique le nombre d'exemples de votre jeu d'apprentissage, pas le nombre de fonctionnalités.
Jetons un coup d'oeil à ma variante de votre code:
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)
Au début, je crée un petit jeu de données aléatoire qui devrait ressembler à ceci:
Comme vous pouvez le constater, j'ai également ajouté la ligne de régression générée et la formule calculée par Excel.
Vous devez faire attention à l'intuition de la régression en utilisant la descente en gradient. Lorsque vous passez un lot complet sur vos données X, vous devez réduire les pertes m de chaque exemple à une seule mise à jour de poids. Dans ce cas, il s'agit de la moyenne de la somme sur les gradients, donc la division par m
.
La prochaine étape à prendre en compte est de suivre la convergence et d’ajuster le taux d’apprentissage. D'ailleurs, vous devriez toujours suivre votre coût à chaque itération, peut-être même l'intrigue.
Si vous exécutez mon exemple, le thêta retourné ressemblera à ceci:
Iteration 99997 | Cost: 47883.706462
Iteration 99998 | Cost: 47883.706462
Iteration 99999 | Cost: 47883.706462
[ 29.25567368 1.01108458]
Ce qui est en fait assez proche de l'équation calculée par Excel (y = x + 30). Notez que lorsque nous avons passé le biais dans la première colonne, la première valeur thêta indique le poids du biais.
Ci-dessous, vous trouverez mon implémentation de la descente de gradient pour un problème de régression linéaire.
Au début, vous calculez le dégradé comme X.T * (X * w - y) / N
et mettez à jour votre thêta actuel avec ce dégradé simultanément.
Voici le code python:
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)
Je sais que cette question a déjà été posée, mais j’ai mis à jour la fonction Gd:
### 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)
Cette fonction réduit l'alpha par rapport à l'itération, ce qui rend la fonction trop convergente plus rapide. Voir Estimation de la régression linéaire avec Gradient Descent (Steepest Descent) pour un exemple en R. J'applique la même logique mais en Python.
Suite à l’implémentation de @ thomas-jungblut en python, j’ai fait de même pour Octave. Si vous trouvez quelque chose qui ne va pas s'il vous plaît faites le moi savoir et je corrigerai + mise à jour.
Les données proviennent d'un fichier txt avec les lignes suivantes:
1 10 1000
2 20 2500
3 25 3500
4 40 5500
5 60 6200
considérez-le comme un échantillon très approximatif de caractéristiques [nombre de chambres] [mts2] et de dernière colonne [prix du loyer], ce que nous voulons prédire.
Voici l'implémentation Octave:
%
% 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);