Я вручную построил алгоритм оптимизации линейного регрессионного градиента без использования встроенной функции для понимания теоретической концепции. Однако, чтобы подтвердить законность моего кода, я сравнил свои коэффициенты и значения перехвата со значениями, полученными из библиотеки 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_))