def fit(self, X, y):
    'Fit the model to the data'
    if self.normalize:
        X = self._feature_scaler.fit_transform(X)
        y = self._target_scaler.fit_transform(y)
    X = X.to_numpy()
    if self.add_intercept:
        X = np.hstack((np.ones((X.shape[0], 1)), X))
    y = y.to_numpy()
    if (self.method == 'normal_equation'):
        self._weights = np.dot(np.dot(np.linalg.inv(np.dot(X.T, X)), X.T), y)
    else:
        self._weights = np.zeros(X.shape[1])
        self.cost_history = ([0] * self.epochs)
        for i in range(self.epochs):
            grad = (np.dot(X.T, (np.dot(X, self._weights) - y)) / y.shape[0])
            self._weights = (self._weights - (self.lr * grad))
            self.cost_history[i] = mse_score(y, np.dot(X, self._weights))
        plt.scatter(range(self.epochs), self.cost_history)
        plt.xlabel('epoch')
        plt.ylabel('mse')
Fit the model to the data
def fit(self, X, y):
    
    if self.normalize:
        X = self._feature_scaler.fit_transform(X)
        y = self._target_scaler.fit_transform(y)
    X = X.to_numpy()
    if self.add_intercept:
        X = np.hstack((np.ones((X.shape[0], 1)), X))
    y = y.to_numpy()
    if (self.method == 'normal_equation'):
        self._weights = np.dot(np.dot(np.linalg.inv(np.dot(X.T, X)), X.T), y)
    else:
        self._weights = np.zeros(X.shape[1])
        self.cost_history = ([0] * self.epochs)
        for i in range(self.epochs):
            grad = (np.dot(X.T, (np.dot(X, self._weights) - y)) / y.shape[0])
            self._weights = (self._weights - (self.lr * grad))
            self.cost_history[i] = mse_score(y, np.dot(X, self._weights))
        plt.scatter(range(self.epochs), self.cost_history)
        plt.xlabel('epoch')
        plt.ylabel('mse')