it-swarm.asia

نزول التدرج باستخدام الثعبان و 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

ثيتا من الكود أعلاه هي 100.2 100.2 ، لكن يجب أن تكون 100.2 61.09 في matlab وهو الصحيح.

55
Madan Ram

أعتقد أن الشفرة معقدة للغاية وتحتاج إلى بنية أكثر ، وإلا فسوف تضيع في جميع المعادلات والعمليات. في النهاية يتلخص هذا الانحدار في أربع عمليات:

  1. احسب الفرضية h = X * theta
  2. احسب الخسارة = h - y وربما التكلفة المربعة (الخسارة ^ 2)/2m
  3. حساب التدرج = X '* الخسارة/م
  4. تحديث المعلمات theta = theta - alpha * التدرج

في حالتك ، أعتقد أنك قد خلطت بين m و n. هنا m تشير إلى عدد الأمثلة في مجموعة التدريب الخاصة بك ، وليس عدد الميزات.

دعنا نلقي نظرة على صيغة بلدي رمز:

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)

في البداية ، أنشئ مجموعة بيانات عشوائية صغيرة يجب أن تبدو كما يلي:

Linear Regression

كما ترى ، أضفت أيضًا خط الانحدار الذي تم إنشاؤه والصيغة التي تم حسابها بواسطة Excel.

تحتاج إلى الحرص على الحدس من الانحدار باستخدام النسب التدرج. أثناء قيامك بتمرير مجموعة كاملة عبر بياناتك X ، تحتاج إلى تقليل خسائر m في كل مثال لتحديث وزن واحد. في هذه الحالة ، هذا هو متوسط ​​المبلغ على التدرجات ، وبالتالي يتم القسمة على m.

الشيء التالي الذي تحتاج إلى العناية به هو تتبع التقارب وضبط معدل التعلم. لهذه المسألة ، يجب عليك دائمًا تتبع التكلفة الخاصة بك في كل تكرار ، وربما حتى تقوم بالتخطيط لها.

إذا قمت بتشغيل مثالي ، فإن ثيتا التي تم إرجاعها ستبدو كما يلي:

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

وهو في الواقع قريب جدًا من المعادلة التي تم حسابها بواسطة Excel (y = x + 30). لاحظ أنه كلما مررنا الانحياز في العمود الأول ، تشير قيمة ثيتا الأولى إلى وزن الانحياز.

124
Thomas Jungblut

يمكنك العثور أدناه على تطبيق تدرج النسب لمشكلة الانحدار الخطي.

في البداية ، تقوم بحساب التدرج مثل X.T * (X * w - y) / N وتحديث ثيتا الحالي باستخدام هذا التدرج اللوني في وقت واحد.

  • X: مصفوفة الميزة
  • y: القيم المستهدفة
  • ث: الأوزان/القيم
  • N: حجم مجموعة التدريب

هنا هو رمز الثعبان:

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

أعلم أن هذا السؤال تم الإجابة عليه بالفعل ، لكنني قمت ببعض التحديث لوظيفة 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)

تقلل هذه الوظيفة من ألفا على التكرار ، مما يجعل الوظيفة تتقارب بشكل أسرع ، انظر تقدير الانحدار الخطي مع هبوط التدرج الحاد (هبوط حاد) على سبيل المثال في R. أطبق المنطق نفسه ولكن في بيثون.

2
Nico Coallier

بعد تنفيذ @ thomas-jungblut في بيثون ، فعلت الشيء نفسه بالنسبة لأوكتاف. إذا وجدت شيئًا خاطئًا ، فيرجى إخبارنا وسوف أقوم بإصلاح + التحديث.

تأتي البيانات من ملف txt مع الصفوف التالية:

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

فكر في الأمر كعينة تقريبية جدًا للميزات [عدد غرف النوم] [mts2] والعمود الأخير [سعر الإيجار] وهو ما نريد التنبؤ به.

هنا هو تطبيق اوكتاف:

%
% 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
Fernando Gabrieli