Batch Gradient Descent
def gradientDescent(X, y, theta, alpha, num_iters):
# Initialize values
J_history = np.zeros((num_iters, 1))
m = X.shape[0]
for i in range(num_iters):
# beta = beta - alpha * (X.T.dot(X.dot(beta)-y)/m)
theta = theta - alpha*(1.0/m) * X.T.dot(X.dot(theta) - np.vstack(Y.T))
# cost history
J_history[i] = cost_function(X, y, theta)
return theta, J_history