diff --git a/ganiyu_olalekan_matthew/Logistic Regression Scratch Implementation.ipynb b/ganiyu_olalekan_matthew/Logistic Regression Scratch Implementation.ipynb new file mode 100644 index 0000000..4e0bbe6 --- /dev/null +++ b/ganiyu_olalekan_matthew/Logistic Regression Scratch Implementation.ipynb @@ -0,0 +1,409 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Importing necessary libraries to run and test the Logistic Regression Algorithm\n", + "\n", + "%matplotlib inline\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from sklearn import datasets\n", + "from sklearn import linear_model" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Loading the sklearn.datasets.load_iris() to use to test the accuracy of the alogorithm\n", + "\n", + "iris = datasets.load_iris()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# The logistic regression class\n", + "\n", + "class LogisticRegression:\n", + " def __init__(self, lr=0.01, num_iter=100, verbose=False, lambd=0.0, fit_intercept=True):\n", + " self.lr = lr\n", + " self.theta = None\n", + " self.lambd = lambd\n", + " self.verbose = verbose\n", + " self.num_iter = num_iter\n", + " self.fit_intercept = fit_intercept\n", + "\n", + " def __l2_regularization(self):\n", + " \"\"\"\n", + " L2 Regularization or Euclidean Normal, used to reduce overfitting.\n", + " \n", + " Could be turned off by leaving lambd set to 0\n", + " \"\"\"\n", + " return (self.lambd / 2) * np.sum(np.square(self.theta)).mean() \n", + " \n", + " @staticmethod\n", + " def __intercept(data):\n", + " intercept = np.ones((data.shape[0], 1))\n", + " return np.concatenate((intercept, data), axis=1)\n", + "\n", + " @staticmethod\n", + " def __sigmoid(z):\n", + " \"\"\"\n", + " The Sigmoid activation function which is best fit for binary classification function\n", + " \"\"\"\n", + " return 1 / (1 + np.exp(-z))\n", + "\n", + " @staticmethod\n", + " def __loss(h, y_hat):\n", + " \"\"\"\n", + " The Cost function\n", + " Turn verbosa (verbosa=True) ON to examine if the cost function is being minimized\n", + " \"\"\"\n", + " return (-y_hat * np.log(h) - (1 - y_hat) * np.log(1 - h)).mean()\n", + "\n", + " def fit(self, data, target):\n", + " \"\"\"\n", + " The fit function used to fit data to model\n", + " \"\"\"\n", + " if self.fit_intercept:\n", + " data = self.__intercept(data)\n", + "\n", + " self.theta = np.zeros((data.shape[1], 1))\n", + "\n", + " for _ in range(self.num_iter):\n", + " z = np.dot(data, self.theta)\n", + " h = self.__sigmoid(z)\n", + " loss = self.__loss(h, target)\n", + " gradient_d = np.dot(data.T, (h - target)) / target.shape[0] + self.__l2_regularization()\n", + " self.theta -= (self.lr * gradient_d)\n", + "\n", + " if self.verbose:\n", + " print(f\"Loss: {loss}\")\n", + "\n", + " def __predict_probability(self, data):\n", + " \"\"\"\n", + " Probability prediction function of data (mostly test data).\n", + " \"\"\"\n", + " return self.__sigmoid(np.dot(self.__intercept(data), self.theta))\n", + "\n", + " def predict(self, test):\n", + " \"\"\"\n", + " rounded prediction of the probability to either 0 or 1, as this is a binary classification model\n", + " \"\"\"\n", + " return self.__predict_probability(test).round()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing data and its target output\n", + "\n", + "# The iris dataset is grouped in fifty's and is of 3 different sets \n", + "# So to test the binary classification algorithm better, took the first 2 sets (the first 100)\n", + "\n", + "X = iris.data[:100, :]\n", + "y = iris.target.reshape(150, 1)[:100, :]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Data spilting\n", + "\n", + "# To avoid inaccuracy, the data is splitted evenly between both datasets\n", + "# 70% training and 30% testing in even distribution\n", + "\n", + "x_train = np.vstack((X[:35, :], X[50:85, :]))\n", + "x_test = np.vstack((X[35:50, :], X[85:100, :]))\n", + "y_train = np.vstack((y[:35, :], y[50:85, :]))\n", + "y_test = np.vstack((y[35:50, :], y[85:100, :]))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Accuracy and data visualization function\n", + "\n", + "def accuracy(prediction, output):\n", + " bool_elem = (prediction == output)\n", + " elem = bool_elem.size\n", + " return (100 / elem) * bool_elem.ravel().tolist().count(True)\n", + "\n", + "\n", + "def data_visualization(data, target, figsize=(10, 6)):\n", + " plt.figure(figsize=figsize)\n", + " plt.scatter(data[:, :1][target == 0], data[:, 1:2][target == 0], color='b', label='Label 0')\n", + " plt.scatter(data[:, :1][target == 1], data[:, 1:2][target == 1], color='r', label='Label 1')\n", + " plt.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlMAAAFlCAYAAADPim3FAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nO3df3Ac5Z3n8c/XM2RtLeQXFrfBwhYpKIoKeGMsB1yhqBi8cRIo8Ueg4kS5PcJtiZMIIcVu5Y6lCF6qXJcDksvtsnZK/Lhi17qELPsD2Aqs2SQuQl2MSybggE3K7IKNHBYb5eLE0TrE9vf+6NEPTyRNj/qZ6Wd63q+qqVE/3er59tMt6aueZ56vubsAAAAwPwvyDgAAAKCVkUwBAABkQDIFAACQAckUAABABiRTAAAAGZBMAQAAZFBOu6GZlSSNSDrg7ldVrbtO0t2SDlSa7nX3++fa3+LFi727u7uuYAEAAPKwc+fOt9y9c6Z1qZMpSTdL2iPpnbOsf9jdP592Z93d3RoZGanj5QEAAPJhZvtmW5fqbT4z65J0paQ57zYBAAC0m7Rjpr4u6UuSTsyxzSfNbJeZPWJmZ820gZn1m9mImY0cOnSo3lgBAACiUzOZMrOrJB10951zbPa4pG53Xy7pKUkPzbSRuw+5e4+793R2zvi2IwAAQEtJM2bqw5J6zewTkhZKeqeZbXH3z05s4O5j07a/X9JdYcMEAACh/OY3v9Ho6KiOHj2adyjRWbhwobq6unTKKaek/p6ayZS73yrpVkkys49I+pPpiVSl/X3u/kZlsVfJQHUAABCh0dFRnXbaaeru7paZ5R1ONNxdY2NjGh0d1dlnn536++Y9z5SZ3WlmvZXFL5jZS2b2gqQvSLpuvvsFAACNdfToUZ1++ukkUlXMTKeffnrdd+zqmRpB7r5N0rbK11+e1j559woAAMSPRGpm8+kXZkAHAABNd+qpp6bedsOGDbrnnnuC7P/JJ5/Ueeedp3POOUdf+cpX6trnbEimAABAWzh+/LhuvPFGPfHEE9q9e7e++c1vavfu3Zn3SzIFAADmNDwsdXdLCxYkz8PDjXmdxx9/XBdffLFWrFihtWvX6s0335xc98ILL2j16tU699xzdd99902233333Vq1apWWL1+uO+64Y87979ixQ+ecc47e//736x3veIfWr1+vRx99NHPcJFMAAGBWw8NSf7+0b5/knjz39zcmobr00ku1fft2/ehHP9L69et1111TMy3t2rVL3/ve9/TDH/5Qd955p376059q69at2rt3r3bs2KHnn39eO3fu1NNPPz3r/g8cOKCzzpqaV7yrq0sHDhyYdfu0SKYAtI1m/XcNFMltt0nj4ye3jY8n7aGNjo5q3bp1uvDCC3X33XfrpZdemlx39dVXa9GiRVq8eLHWrFmjHTt2aOvWrdq6datWrFihiy66SC+//LL27t0bPrAa6vo0HwC0qon/rif+KEz8dy1JfX35xQXEbv/++tqzuOmmm3TLLbeot7dX27Zt04YNGybXVX/Kzszk7rr11lt1ww03pNr/kiVL9Prrr08uj46OasmSJZnj5s4UgLbQzP+ugSJZurS+9iwOHz48mdw89NDJlekeffRRHT16VGNjY9q2bZtWrVqldevW6cEHH9SRI0ckJW/jHTx4cNb9r1q1Snv37tWrr76qt99+W9/61rfU29s76/ZpcWcKQFto5n/XQJFs3HjyXV1J6uhI2rMYHx9XV1fX5PItt9yiDRs26Nprr9V73vMeXX755Xr11Vcn1y9fvlxr1qzRW2+9pdtvv11nnnmmzjzzTO3Zs0erV6+WlEyHsGXLFp1xxhkzvma5XNa9996rdevW6fjx47r++uv1gQ98INuBSDJ3z7yT+ejp6fGRkZFcXhtA++nuTt7aq7ZsmfTaa82OBsjXnj17dP7556fefng4uYu7f39yR2rjxmK/PT5T/5jZTnfvmWl73uYD0BY2bkz+m54uxH/XQDvo60v+6ThxInkuciI1HyRTANpCX580NJTciTJLnoeG+KMAIDvGTAFoG319JE8AwuPOFAAAQAYkUwAAABmQTAEAAGRAMgUAAJru1FNPTb3thg0bdM899wTZ//XXX68zzjhDF1xwQV37mwvJFAAAaBvXXXednnzyyaD7JJkCAABza1KV8Mcff1wXX3yxVqxYobVr1+rNN9+cXPfCCy9o9erVOvfcc3XfffdNtt99991atWqVli9frjvuuKPma1x22WV673vfGzRupkYAAACza2KV8EsvvVTbt2+Xmen+++/XXXfdpa9+9auSpF27dmn79u361a9+pRUrVujKK6/Uiy++qL1792rHjh1yd/X29urpp5/WZZddFjSuWkimAADA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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "data_visualization(X, y)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Initializing the model at the default 100 iteration\n", + "\n", + "model = LogisticRegression()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 29.4 ms, sys: 4.28 ms, total: 33.7 ms\n", + "Wall time: 29.9 ms\n" + ] + } + ], + "source": [ + "# Time Measurement\n", + "\n", + "%time model.fit(x_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 100.0\n" + ] + } + ], + "source": [ + "# Accuracy Measurement in %\n", + "\n", + "prediction = model.predict(x_test)\n", + "print(f\"Accuracy: {accuracy(prediction, y_test)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 19.5 ms, sys: 7.93 ms, total: 27.5 ms\n", + "Wall time: 203 ms\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/olalekan/.local/lib/python3.6/site-packages/sklearn/utils/validation.py:760: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().\n", + " y = column_or_1d(y, warn=True)\n" + ] + }, + { + "data": { + "text/plain": [ + "LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n", + " intercept_scaling=1, l1_ratio=None, max_iter=100,\n", + " multi_class='auto', n_jobs=None, penalty='l2',\n", + " random_state=None, solver='lbfgs', tol=0.0001, verbose=0,\n", + " warm_start=False)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Comparing with the scikit learn Logistic Regression class\n", + "\n", + "# max_iter=100 the default\n", + "\n", + "sk_model = linear_model.LogisticRegression()\n", + "\n", + "%time sk_model.fit(x_train, y_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 50.0\n" + ] + } + ], + "source": [ + "# Comparing with the scikit learn Logistic Regression class\n", + "# Accuracy Measurement in %\n", + "\n", + "prediction = sk_model.predict(x_test)\n", + "print(f\"Accuracy: {accuracy(prediction, y_test)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 15.8 ms, sys: 0 ns, total: 15.8 ms\n", + "Wall time: 14.3 ms\n", + "Accuracy: 100.0\n" + ] + } + ], + "source": [ + "# Testing model with 50 iterations\n", + "\n", + "\n", + "model = LogisticRegression(num_iter=50)\n", + "\n", + "%time model.fit(x_train, y_train)\n", + "\n", + "prediction = model.predict(x_test)\n", + "print(f\"Accuracy: {accuracy(prediction, y_test)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 6.02 ms, sys: 3.61 ms, total: 9.63 ms\n", + "Wall time: 8.48 ms\n", + "Accuracy: 96.66666666666667\n" + ] + } + ], + "source": [ + "# Testing model with 30 iterations\n", + "\n", + "\n", + "model = LogisticRegression(num_iter=30)\n", + "\n", + "%time model.fit(x_train, y_train)\n", + "\n", + "prediction = model.predict(x_test)\n", + "print(f\"Accuracy: {accuracy(prediction, y_test)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 13.5 ms, sys: 285 µs, total: 13.8 ms\n", + "Wall time: 12.2 ms\n", + "Accuracy: 100.0\n" + ] + } + ], + "source": [ + "# Testing model with 30 iterations and applying regularization\n", + "\n", + "\n", + "model = LogisticRegression(num_iter=30, lambd=0.5)\n", + "\n", + "%time model.fit(x_train, y_train)\n", + "\n", + "prediction = model.predict(x_test)\n", + "print(f\"Accuracy: {accuracy(prediction, y_test)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/ganiyu_olalekan_matthew/README.md b/ganiyu_olalekan_matthew/README.md new file mode 100644 index 0000000..cf67fb8 --- /dev/null +++ b/ganiyu_olalekan_matthew/README.md @@ -0,0 +1,17 @@ +# ML-Logistic-regression-algorithm-challenge + +Data Science Nigeria (DSN) open challenge on implementing a Logistic Regression algorithm from scratch using Python or R programming. + + +## Logistic Regression + +Logistic regression is the appropriate regression analysis to conduct when the dependent variable is binary. Like all regression analyses, the logistic regression is a predictive analysis. Logistic regression is used to describe data and to explain the relationship between one dependent binary variable and one or more nominal, ordinal, interval or ratio-level independent variables. + +## Implemetation + +The Logistic Regression algorithm was implemented with python using jupyter notebook. + +The iris dataset from sklearn.datasets.load_iris() was used to test the speed and accuracy of the algorithm. Unlike the default iris dataset, my implementation modified it to match the binary requirement of the logistic regression algorithm. Given that the algorithm (Logistic Algorithm) is a Binary Classification Algorithm. + +L2 Regularization (Euclidean Normal) was also implemented to optimize the algorithm, obtaining same accuracy in fewer iterations as it would have been for longer iterations. +