Source code for models.logreg

import numpy as np

[docs] class LogisticRegression: """ :param input: The input data matrix of shape (n, m), where n is the number of features and m is the number of samples :type input: numpy.ndarray :param labels: The target labels of shape (1, m), where m is the number of samples. :type labels: numpy.ndarray :param num_features: The number of features in the input data. :type num_features: int :param alpha: The learning rate for gradient descent. :type alpha: float :param epochs: The number of epochs for training. :type epochs: int """ def __init__(self, input, labels, num_features, alpha, epochs): self.input = input self.labels = labels self.num_features = num_features self.alpha = alpha self.epochs = epochs self.outputs = [] self.params = [] self.gradients = [] self.pred = None self.l = None
[docs] def init_params(self): """ Initialize the parameters (weights and bias) for the logistic regression model. :return: Tuple containing the weights (w) and bias (b). :rtype: tuple """ w = np.random.rand(1, self.num_features) b = np.random.rand(1, 1) self.params = w, b return self.params
[docs] def sigmoid(self, z): """ Calculate the sigmoid function for a given input. :param z: The input value. :type z: float or numpy.ndarray :return: The sigmoid of z. :rtype: float or numpy.ndarray """ self.pred = 1 / (1 + np.exp(-z)) return self.pred
[docs] def forward(self): """ Perform a forward pass to calculate the predicted probabilities. :return: The predicted probabilities. :rtype: numpy.ndarray """ w, b = self.params z = np.dot(w, self.input) + b self.pred = self.sigmoid(z) return self.pred
[docs] def log_loss(self): """ Calculate the logistic loss (cross-entropy) between the predicted and actual labels. :return: The logistic loss. :rtype: float """ eps = 1e-10 self.l = - np.mean(self.labels * np.log(self.pred + eps) + (1 - self.labels) * np.log(1 - self.pred + eps)) return self.l
[docs] def backward(self): """ Perform a backward pass to calculate the gradients of the weights and bias. :return: Tuple containing the gradients of the weights (dw) and bias (db). :rtype: tuple """ dw = np.dot((self.pred - self.labels), self.input.T) db = np.mean(self.pred - self.labels, axis = 0, keepdims = True) self.gradients = dw, db return self.gradients
[docs] def update(self): """ Update the weights and bias using gradient descent. :return: Tuple containing the updated weights (w) and bias (b). :rtype: tuple """ dw, db = self.gradients w, b = self.params w = w - self.alpha * dw b = b - self.alpha * db self.params = w, b return self.params
[docs] def gradient_descent(self): """ Perform gradient descent to train the logistic regression model. :return: Tuple containing the final weights (w) and bias (b). :rtype: tuple """ w, b = self.params for epoch in range(self.epochs): self.pred = self.forward() self.l = self.log_loss() self.gradients = self.backward() self.params = self.update() print(f"Epoch: {epoch}") print(f"Loss: {self.l}") return self.params
[docs] def model(self): """ Run the entire logistic regression model. :return: Tuple containing the final weights (w) and bias (b). :rtype: tuple """ self.params = self.init_params() self.params = self.gradient_descent() return self.params