class_docstr: Logistic Regression classifier.
  Parameters:
  -----------
  learning_rate: float
      The step length that will be taken when following the negative gradient during
      training.
  gradient_descent: boolean
      True or false depending if gradient descent should be used when training. If
      false then we use batch optimization by least squares.
code: def fit(self, X, y, n_iterations=4000):
      self._initialize_parameters(X)
      # Tune parameters for n iterations
      for i in range(n_iterations):
          # Make a new prediction
          y_pred = self.sigmoid(X.dot(self.param))
          if self.gradient_descent:
              # Move against the gradient of the loss function with
              # respect to the parameters to minimize the loss
              self.param -= self.learning_rate * -(y - y_pred).dot(X)
          else:
              # Make a diagonal matrix of the sigmoid gradient column vector
              diag_gradient = make_diagonal(
                  self.sigmoid.gradient(X.dot(self.param))
              )
              # Batch opt:
              self.param = (
                  np.linalg.pinv(X.T.dot(diag_gradient).dot(X))
                  .dot(X.T)
                  .dot(
                      diag_gradient.dot(X).dot(self.param) + y - y_pred
                  )
              )
  
file_path: ML-From-Scratch/mlfromscratch/supervised_learning/logistic_regression.py
imports: from __future__ import print_function, division
  import numpy
  import math
  from mlfromscratch.utils import make_diagonal, Plot
  from mlfromscratch.deep_learning.activation_functions import Sigmoid
label_desc: Use image node_id 3 for calling the LogisticRegression obj's underlying member method code with example usage: obj.fit(X, y, n_iterations) without return types