почему мой J против тета-графика не является чашеобразной кривой согласно теории градиентного спуска? - PullRequest
0 голосов
/ 15 января 2020

Я вручную построил алгоритм оптимизации линейного регрессионного градиента без использования встроенной функции для понимания теоретической концепции. Однако, чтобы подтвердить законность моего кода, я сравнил свои коэффициенты и значения перехвата со значениями, полученными из библиотеки python sklearn, и обнаружил, они почти совпадают .

Однако, когда Я построил функцию стоимости в зависимости от тета-значений, я не получаю кривую формы чаши в соответствии с теорией градиентного спуска.

Скажите, пожалуйста, есть ли ошибка в моем коде (ручная реализация) и почему я не получаю кривую формы чаши?

ручная реализация:

import pandas as pd
import numpy as np
import seaborn as sb
import matplotlib.pyplot as plt
from sklearn.linear_model import SGDRegressor

Data = pd.DataFrame({'X': list(np.arange(0,10)), 'Y': [1,3,2,5,7,8,8,9,10,12]})
#print(Data.tail())

sb.scatterplot(x ='X', y = 'Y', data = Data)
plt.show()

# creating function to select batches from data (stochastic GD)
def next_batch(X, Y, batchSize):
    for i in np.arange(0, X.shape[0], batchSize):
        yield (X[i:i + batchSize], Y[i:i + batchSize])

# appending column of ones to original data to satisfy dot product criterion
X_new= np.c_[np.ones((Data['X'].shape[0])), Data['X'].values]

# fetching Y
Y = Data['Y'].values.reshape(-1,1)

m = X_new.shape[0] # no.of samples
n = X_new.shape[1]

# innitializing theta
theta = np.random.uniform(low = 0, high = 1, size = n).reshape(-1,1)

# initialising arrays to store values
theta_history = [theta.flatten().tolist()]
J_history = []

# stochastic gradient descent implementation
iterations = 15000
alpha = 0.002

for epoch in np.arange(0, iterations):
    epochLoss = []
    theta_epochs = []

    for (batchX, batchY) in next_batch(X_new, Y, m):
        H = batchX.dot(theta)
        error = H - batchY
        J = np.sum(error ** 2)/(2 * m)
        epochLoss.append(J)
        Gradient = batchX.T.dot(error)/m
        theta = theta - alpha * Gradient
        theta_epochs.append(theta)

    J_history.append(np.average(epochLoss))
    if epoch == iterations-1:
        break
    else:
        a = np.concatenate(theta_epochs, axis = 1)
        theta_history.append(a.mean(axis=1).flatten().tolist())

# fectching index value of min(J)
idx = J_history.index(min(J_history))

# fetching and printing optimum coefficient and intercept values
print('intercept: {}, coeff: {}'.format(theta_history[idx][0], theta_history[idx][1]))

# plotting J vs theta 
theta_k = [i[1] for i in theta_history] 
sb.scatterplot(theta_k, J)
plt.show()

встроенная библиотека sklearn:

import pandas as pd
import numpy as np
import seaborn as sb
import matplotlib.pyplot as plt
from sklearn.linear_model import SGDRegressor

Data = pd.DataFrame({'X': list(np.arange(0,10)), 'Y': [1,3,2,5,7,8,8,9,10,12]})
#print(Data.tail())

sb.scatterplot(x ='X', y = 'Y', data = Data)
plt.show()

# builtin function
model = SGDRegressor(eta0=0.002, learning_rate='constant', loss='squared_loss', max_iter=15000, shuffle=False, tol=None)
model.fit(Data['X'].values.reshape(-1,1), Data['Y'].values.reshape(-1))

print('intercept: {}, coeff: {}'.format( model.intercept_, model.coef_))
...