# Stochastic Gradient Descent (SGD) implementation for linear regressiondef sgd(X, y, learning_rate=0.01, n_iterations=1000): m, n = X.shape theta = np.random.randn(n, 1) # Initialize theta with random values y = y.values.reshape(-1, 1) # Reshape y to be a column vector mse_history = [] # List to store MSE values over iterations for iteration in range(n_iterations): for i in range(m): random_index = np.random.randint(m) Xi = X[random_index:random_index+1] yi = y[random_index:random_index+1] gradients = 2 * Xi.T.dot(Xi.dot(theta) - yi) theta = theta - learning_rate * gradients # b = b - learning_rate * gradient_b where gradient_b = -2/n * np.sum(error) # Store MSE for every iteration mse = np.mean((X.dot(theta) - y) ** 2) mse_history.append(mse) if iteration % 100 == 0 and iteration != 0: print(f"Iteration {iteration}: MSE = {mse}") return theta, mse_history