From c87cded9e1b375dc47ee3b574691fd515c7e7a8c Mon Sep 17 00:00:00 2001 From: Jean N'dah Kouagou Date: Tue, 12 Nov 2019 22:10:11 +0000 Subject: [PATCH] second commit 12/11/2019 --- My-Logistic-regression-Mini_batch_SGD.ipynb | 906 ++++++++++++++++++++ 1 file changed, 906 insertions(+) create mode 100644 My-Logistic-regression-Mini_batch_SGD.ipynb diff --git a/My-Logistic-regression-Mini_batch_SGD.ipynb b/My-Logistic-regression-Mini_batch_SGD.ipynb new file mode 100644 index 0000000..4857a11 --- /dev/null +++ b/My-Logistic-regression-Mini_batch_SGD.ipynb @@ -0,0 +1,906 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import random as rd\n", + "import numpy as np\n", + "import seaborn as sn\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "mu1 = -1\n", + "mu2 = 3\n", + "sig1 = 0.5\n", + "sig2 = 1\n", + "N = 300\n", + "np.random.seed(10)\n", + "x11=np.random.randn(N,1)*sig1 + mu1+1\n", + "x12=np.random.randn(N,1)*sig1 + mu1+4\n", + "x21=np.random.randn(N,1)*sig2 + mu2+1\n", + "x22=np.random.randn(N,1)*sig2 + mu2+4\n", + "c = np.vstack((np.zeros((N,1)), np.ones((N,1))))\n", + "x1 = np.hstack((x11,x12))\n", + "x2 = np.hstack((x21,x22))\n", + "\n", + "X = np.hstack( (np.vstack( (x1,x2) ),c) )\n", + "np.random.shuffle(X)\n", + "dataset = pd.DataFrame(data=X, columns=['x','y','c'])\n", + "\n", + "\n", + "## Pseudo code used: pseudo code in class \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 133, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
xyc
03.8916408.8246691.0
10.4462823.4567420.0
2-0.1287673.3685890.0
3-0.2000693.2174690.0
42.6876098.3793381.0
\n", + "
" + ], + "text/plain": [ + " x y c\n", + "0 3.891640 8.824669 1.0\n", + "1 0.446282 3.456742 0.0\n", + "2 -0.128767 3.368589 0.0\n", + "3 -0.200069 3.217469 0.0\n", + "4 2.687609 8.379338 1.0" + ] + }, + "execution_count": 133, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dataset.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.scatter(dataset[dataset['c']==0]['x'], dataset[dataset['c']==0]['y'], marker='o',s=25, color='g')\n", + "plt.scatter(dataset[dataset['c']>0]['x'], dataset[dataset['c']>0]['y'], marker='o',s=25, color='r')\n", + "plt.legend(['Class 0', 'Class 1'])" + ] + }, + { + "cell_type": "code", + "execution_count": 135, + "metadata": {}, + "outputs": [], + "source": [ + "# !pip uninstall ipnb " + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "metadata": {}, + "outputs": [], + "source": [ + "import ipdb" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": {}, + "outputs": [], + "source": [ + "class Jean_logisticRegression(object):\n", + " \n", + " def __init__(self, features, target, params, lr=0.05, tolerance=1e-4, Max_iter=400, verbose=True):\n", + " self.features=features\n", + " self.target=target\n", + " self.lr=lr\n", + " self.tolerance=tolerance\n", + " self.Max_iter=Max_iter\n", + " self.params=params\n", + " self.verbose=verbose\n", + " \n", + " def add_intercept(self, intercept):\n", + " self.intercept=intercept\n", + " self.features=np.hstack([self.intercept, self.features])\n", + " print(\"Intercept added successfully\")\n", + " \n", + " def sigmoid(self, x):\n", + " return 1./(1+np.exp(-x))\n", + "\n", + " def get_gradient(self, theta, X, y):\n", + " #ipdb.set_trace\n", + " return np.dot(y-self.sigmoid(np.dot(theta, X)), X)\n", + " \n", + " def loss(self):\n", + " return (-1.0/len(self.target))*sum([self.target[i]*np.log(self.sigmoid(np.dot(self.params, self.features[i,:])))+(1-self.target[i])*np.log(1-self.sigmoid(np.dot(self.params, self.features[i,:]))) for i in range(len(self.target))])\n", + " \n", + " def fit(self):\n", + " Norm=np.linalg.norm\n", + " Iter=0\n", + " old_params=self.params+1\n", + " while(Norm(self.params-old_params)>self.tolerance and Iter<=self.Max_iter):\n", + " old_params=self.params\n", + " indices=list(range(self.features.shape[0]))\n", + " np.random.shuffle(indices)\n", + " # We just change the way we compute the gradient\n", + " Mini_batch=indices[:50]\n", + " #print(Mini_batch)\n", + " gradient=sum([self.get_gradient(self.params, self.features[i,:], self.target[i]) for i in Mini_batch])\n", + " self.params=self.params+self.lr*gradient\n", + " if self.verbose:\n", + " print(\"Loss: %.6f\"%self.loss())\n", + " Iter += 1\n", + " print('Number of iterations:', Iter-1)\n", + " return self.params\n", + " \n", + " def predict(self, Features):\n", + " Predictions=[]\n", + " Intercept=np.ones(Features.shape[0]).reshape(-1,1)\n", + " Features=np.hstack([Intercept, Features])\n", + " for i in range(Features.shape[0]):\n", + " if self.sigmoid(np.dot(Features[i,:], self.params))>0.5:\n", + " Predictions.append(1.0)\n", + " else:\n", + " Predictions.append(0.0)\n", + "\n", + "\n", + " return np.array(Predictions)" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [], + "source": [ + "mu1 = -1\n", + "mu2 = 3\n", + "sig1 = 0.5\n", + "sig2 = 1\n", + "N = 300\n", + "np.random.seed(10)\n", + "x11=np.random.randn(N,1)*sig1 + mu1\n", + "x12=np.random.randn(N,1)*sig1 + mu1+3\n", + "x21=np.random.randn(N,1)*sig2 + mu2\n", + "x22=np.random.randn(N,1)*sig2 + mu2+3\n", + "c = np.vstack((np.zeros((N,1)), np.ones((N,1))))\n", + "x1 = np.hstack((x11,x12))\n", + "x2 = np.hstack((x21,x22))\n", + "\n", + "X = np.hstack( (np.vstack( (x1,x2) ),c) )\n", + "np.random.shuffle(X)\n", + "#dataset = pd.DataFrame(data=X, columns=['x','y','c'])\n", + "\n", + "\n", + "## Pseudo code used: pseudo code in class \n", + "\n", + "\n", + "Features=X[:,:-1]\n", + "Target=X[:,-1]\n", + "theta=np.random.randn(1+Features.shape[1])\n", + "\n", + "\n", + "logistic_regression=Jean_logisticRegression(features=Features, target=Target, params=theta, lr=0.005, Max_iter=500, verbose=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Intercept added successfully\n" + ] + } + ], + "source": [ + "Intercept_column=np.ones_like(Target).reshape(-1,1)\n", + "logistic_regression.add_intercept(Intercept_column)" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loss: 1.150983\n", + "Loss: 0.979947\n", + "Loss: 0.846801\n", + "Loss: 0.706980\n", + "Loss: 0.595855\n", + "Loss: 0.520620\n", + "Loss: 0.457658\n", + "Loss: 0.398156\n", + "Loss: 0.354607\n", + "Loss: 0.321788\n", + "Loss: 0.288885\n", + "Loss: 0.264527\n", + "Loss: 0.243623\n", + "Loss: 0.226244\n", + "Loss: 0.213946\n", + "Loss: 0.201565\n", + "Loss: 0.191626\n", + "Loss: 0.180944\n", + "Loss: 0.172081\n", + "Loss: 0.164624\n", + "Loss: 0.157714\n", + "Loss: 0.151254\n", + "Loss: 0.144335\n", + "Loss: 0.138438\n", + "Loss: 0.134346\n", + "Loss: 0.130916\n", + "Loss: 0.127480\n", + "Loss: 0.123197\n", + "Loss: 0.119236\n", + "Loss: 0.115837\n", + "Loss: 0.113253\n", + "Loss: 0.109153\n", + "Loss: 0.106763\n", + "Loss: 0.103925\n", + "Loss: 0.101612\n", + "Loss: 0.099622\n", + "Loss: 0.097530\n", + "Loss: 0.096053\n", + "Loss: 0.093885\n", + "Loss: 0.091071\n", + "Loss: 0.089595\n", + "Loss: 0.087697\n", + "Loss: 0.086520\n", + "Loss: 0.084519\n", + "Loss: 0.082925\n", + "Loss: 0.081511\n", + "Loss: 0.080432\n", + "Loss: 0.079138\n", + "Loss: 0.077786\n", + "Loss: 0.076823\n", + "Loss: 0.075543\n", + "Loss: 0.074555\n", + "Loss: 0.073944\n", + "Loss: 0.073179\n", + "Loss: 0.071709\n", + "Loss: 0.070638\n", + "Loss: 0.069240\n", + "Loss: 0.068320\n", + "Loss: 0.067510\n", + "Loss: 0.066840\n", + "Loss: 0.065867\n", + "Loss: 0.065083\n", + "Loss: 0.064309\n", + "Loss: 0.063525\n", + "Loss: 0.062724\n", + "Loss: 0.062109\n", + "Loss: 0.061548\n", + "Loss: 0.061015\n", + "Loss: 0.060483\n", + "Loss: 0.059726\n", + "Loss: 0.058925\n", + "Loss: 0.058346\n", + "Loss: 0.057701\n", + "Loss: 0.057233\n", + "Loss: 0.056797\n", + "Loss: 0.056469\n", + "Loss: 0.055832\n", + "Loss: 0.055111\n", + "Loss: 0.054533\n", + "Loss: 0.054054\n", + "Loss: 0.053646\n", + "Loss: 0.053264\n", + "Loss: 0.052992\n", + "Loss: 0.052603\n", + "Loss: 0.052273\n", + "Loss: 0.051562\n", + "Loss: 0.051373\n", + "Loss: 0.050839\n", + "Loss: 0.050676\n", + "Loss: 0.050392\n", + "Loss: 0.049546\n", + "Loss: 0.049015\n", + "Loss: 0.048783\n", + "Loss: 0.048237\n", + "Loss: 0.047929\n", + "Loss: 0.047576\n", + "Loss: 0.047148\n", + "Loss: 0.046790\n", + "Loss: 0.046468\n", + "Loss: 0.046113\n", + "Loss: 0.045792\n", + "Loss: 0.045517\n", + "Loss: 0.045122\n", + "Loss: 0.044771\n", + "Loss: 0.044519\n", + "Loss: 0.044233\n", + "Loss: 0.043976\n", + "Loss: 0.043699\n", + "Loss: 0.043447\n", + "Loss: 0.043141\n", + "Loss: 0.042887\n", + "Loss: 0.042633\n", + "Loss: 0.042342\n", + "Loss: 0.042114\n", + "Loss: 0.041998\n", + "Loss: 0.041684\n", + "Loss: 0.041426\n", + "Loss: 0.041382\n", + "Loss: 0.041028\n", + "Loss: 0.041009\n", + "Loss: 0.040684\n", + "Loss: 0.040420\n", + "Loss: 0.040096\n", + "Loss: 0.039811\n", + "Loss: 0.039592\n", + "Loss: 0.039398\n", + "Loss: 0.039189\n", + "Loss: 0.038961\n", + "Loss: 0.038747\n", + "Loss: 0.038972\n", + "Loss: 0.038715\n", + "Loss: 0.038578\n", + "Loss: 0.038000\n", + "Loss: 0.037805\n", + "Loss: 0.037541\n", + "Loss: 0.037339\n", + "Loss: 0.037144\n", + "Loss: 0.036905\n", + "Loss: 0.036772\n", + "Loss: 0.036657\n", + "Loss: 0.036408\n", + "Loss: 0.036214\n", + "Loss: 0.036072\n", + "Loss: 0.035845\n", + "Loss: 0.035742\n", + "Loss: 0.035540\n", + "Loss: 0.035283\n", + "Loss: 0.035139\n", + "Loss: 0.034990\n", + "Loss: 0.034806\n", + "Loss: 0.034653\n", + "Loss: 0.034516\n", + "Loss: 0.034322\n", + "Loss: 0.034181\n", + "Loss: 0.034064\n", + "Loss: 0.033935\n", + "Loss: 0.033777\n", + "Loss: 0.033606\n", + "Loss: 0.033499\n", + "Loss: 0.033335\n", + "Loss: 0.033105\n", + "Loss: 0.033004\n", + "Loss: 0.032852\n", + "Loss: 0.032710\n", + "Loss: 0.032638\n", + "Loss: 0.032491\n", + "Loss: 0.032395\n", + "Loss: 0.032239\n", + "Loss: 0.032121\n", + "Loss: 0.032242\n", + "Loss: 0.032040\n", + "Loss: 0.031952\n", + "Loss: 0.031806\n", + "Loss: 0.031545\n", + "Loss: 0.031418\n", + "Loss: 0.031344\n", + "Loss: 0.031121\n", + "Loss: 0.030996\n", + "Loss: 0.030822\n", + "Loss: 0.030741\n", + "Loss: 0.030614\n", + "Loss: 0.030501\n", + "Loss: 0.030419\n", + "Loss: 0.030366\n", + "Loss: 0.030259\n", + "Loss: 0.030099\n", + "Loss: 0.029979\n", + "Loss: 0.029881\n", + "Loss: 0.029817\n", + "Loss: 0.029799\n", + "Loss: 0.029645\n", + "Loss: 0.029496\n", + "Loss: 0.029575\n", + "Loss: 0.029431\n", + "Loss: 0.029415\n", + "Loss: 0.029265\n", + "Loss: 0.029331\n", + "Loss: 0.029077\n", + "Loss: 0.028940\n", + "Loss: 0.028742\n", + "Loss: 0.028659\n", + "Loss: 0.028611\n", + "Loss: 0.028616\n", + "Loss: 0.028423\n", + "Loss: 0.028244\n", + "Loss: 0.028145\n", + "Loss: 0.028082\n", + "Loss: 0.028008\n", + "Loss: 0.027986\n", + "Loss: 0.027881\n", + "Loss: 0.027760\n", + "Loss: 0.027626\n", + "Loss: 0.027529\n", + "Loss: 0.027465\n", + "Loss: 0.027316\n", + "Loss: 0.027232\n", + "Loss: 0.027230\n", + "Loss: 0.027107\n", + "Loss: 0.027050\n", + "Loss: 0.026926\n", + "Loss: 0.026819\n", + "Loss: 0.026735\n", + "Loss: 0.026659\n", + "Loss: 0.026589\n", + "Loss: 0.026511\n", + "Loss: 0.026385\n", + "Loss: 0.026319\n", + "Loss: 0.026209\n", + "Loss: 0.026204\n", + "Loss: 0.026122\n", + "Loss: 0.026028\n", + "Loss: 0.025940\n", + "Loss: 0.025870\n", + "Loss: 0.025821\n", + "Loss: 0.025731\n", + "Loss: 0.025740\n", + "Loss: 0.025682\n", + "Loss: 0.025514\n", + "Loss: 0.025447\n", + "Loss: 0.025373\n", + "Loss: 0.025333\n", + "Loss: 0.025269\n", + "Loss: 0.025163\n", + "Loss: 0.025100\n", + "Loss: 0.025042\n", + "Loss: 0.025050\n", + "Loss: 0.024973\n", + "Loss: 0.024845\n", + "Loss: 0.024837\n", + "Loss: 0.024782\n", + "Loss: 0.024635\n", + "Loss: 0.024596\n", + "Loss: 0.024443\n", + "Loss: 0.024354\n", + "Loss: 0.024276\n", + "Loss: 0.024197\n", + "Loss: 0.024146\n", + "Loss: 0.024094\n", + "Loss: 0.024074\n", + "Loss: 0.024004\n", + "Loss: 0.023956\n", + "Loss: 0.023885\n", + "Loss: 0.023882\n", + "Loss: 0.023748\n", + "Loss: 0.023693\n", + "Loss: 0.023658\n", + "Loss: 0.023566\n", + "Loss: 0.023510\n", + "Loss: 0.023464\n", + "Loss: 0.023355\n", + "Loss: 0.023306\n", + "Loss: 0.023241\n", + "Loss: 0.023201\n", + "Loss: 0.023136\n", + "Loss: 0.023083\n", + "Loss: 0.023034\n", + "Loss: 0.022995\n", + "Loss: 0.022939\n", + "Loss: 0.022902\n", + "Loss: 0.022855\n", + "Loss: 0.022816\n", + "Loss: 0.022738\n", + "Loss: 0.022642\n", + "Loss: 0.022606\n", + "Loss: 0.022545\n", + "Loss: 0.022488\n", + "Loss: 0.022431\n", + "Loss: 0.022393\n", + "Loss: 0.022349\n", + "Loss: 0.022308\n", + "Loss: 0.022268\n", + "Loss: 0.022246\n", + "Loss: 0.022217\n", + "Loss: 0.022209\n", + "Loss: 0.022192\n", + "Loss: 0.022204\n", + "Loss: 0.022159\n", + "Loss: 0.022147\n", + "Loss: 0.022073\n", + "Loss: 0.022088\n", + "Loss: 0.021964\n", + "Loss: 0.021942\n", + "Loss: 0.021722\n", + "Loss: 0.021666\n", + "Loss: 0.021682\n", + "Loss: 0.021641\n", + "Loss: 0.021603\n", + "Loss: 0.021541\n", + "Loss: 0.021476\n", + "Loss: 0.021449\n", + "Loss: 0.021401\n", + "Loss: 0.021416\n", + "Loss: 0.021393\n", + "Loss: 0.021323\n", + "Loss: 0.021260\n", + "Loss: 0.021192\n", + "Loss: 0.021138\n", + "Loss: 0.021097\n", + "Loss: 0.021080\n", + "Loss: 0.021043\n", + "Loss: 0.020936\n", + "Loss: 0.020892\n", + "Loss: 0.020881\n", + "Loss: 0.020820\n", + "Loss: 0.020797\n", + "Loss: 0.020761\n", + "Loss: 0.020749\n", + "Loss: 0.020749\n", + "Loss: 0.020697\n", + "Loss: 0.020575\n", + "Loss: 0.020575\n", + "Loss: 0.020559\n", + "Loss: 0.020543\n", + "Loss: 0.020494\n", + "Loss: 0.020481\n", + "Loss: 0.020368\n", + "Loss: 0.020356\n", + "Loss: 0.020342\n", + "Loss: 0.020326\n", + "Loss: 0.020221\n", + "Loss: 0.020197\n", + "Loss: 0.020170\n", + "Loss: 0.020155\n", + "Loss: 0.020092\n", + "Loss: 0.020062\n", + "Loss: 0.020035\n", + "Loss: 0.019973\n", + "Loss: 0.019935\n", + "Loss: 0.019888\n", + "Loss: 0.019863\n", + "Loss: 0.019847\n", + "Loss: 0.019772\n", + "Loss: 0.019743\n", + "Loss: 0.019691\n", + "Loss: 0.019670\n", + "Loss: 0.019619\n", + "Loss: 0.019592\n", + "Loss: 0.019555\n", + "Loss: 0.019525\n", + "Loss: 0.019492\n", + "Loss: 0.019460\n", + "Loss: 0.019439\n", + "Loss: 0.019394\n", + "Loss: 0.019370\n", + "Loss: 0.019329\n", + "Loss: 0.019316\n", + "Loss: 0.019305\n", + "Loss: 0.019308\n", + "Loss: 0.019228\n", + "Loss: 0.019162\n", + "Loss: 0.019136\n", + "Loss: 0.019112\n", + "Loss: 0.019070\n", + "Loss: 0.019045\n", + "Loss: 0.019016\n", + "Loss: 0.018974\n", + "Loss: 0.018996\n", + "Loss: 0.018975\n", + "Loss: 0.018949\n", + "Loss: 0.018912\n", + "Loss: 0.018879\n", + "Loss: 0.018857\n", + "Loss: 0.018778\n", + "Loss: 0.018728\n", + "Loss: 0.018694\n", + "Loss: 0.018648\n", + "Loss: 0.018622\n", + "Loss: 0.018596\n", + "Loss: 0.018566\n", + "Loss: 0.018549\n", + "Loss: 0.018555\n", + "Loss: 0.018524\n", + "Loss: 0.018561\n", + "Loss: 0.018447\n", + "Loss: 0.018410\n", + "Loss: 0.018361\n", + "Loss: 0.018326\n", + "Loss: 0.018313\n", + "Loss: 0.018293\n", + "Loss: 0.018307\n", + "Loss: 0.018314\n", + "Loss: 0.018294\n", + "Loss: 0.018200\n", + "Loss: 0.018229\n", + "Loss: 0.018227\n", + "Loss: 0.018222\n", + "Loss: 0.018209\n", + "Loss: 0.018177\n", + "Loss: 0.018169\n", + "Loss: 0.018198\n", + "Loss: 0.018176\n", + "Loss: 0.018191\n", + "Loss: 0.018171\n", + "Loss: 0.018204\n", + "Loss: 0.018102\n", + "Loss: 0.017996\n", + "Loss: 0.017837\n", + "Loss: 0.017784\n", + "Loss: 0.017743\n", + "Loss: 0.017734\n", + "Loss: 0.017702\n", + "Loss: 0.017620\n", + "Loss: 0.017597\n", + "Loss: 0.017585\n", + "Loss: 0.017574\n", + "Loss: 0.017498\n", + "Loss: 0.017487\n", + "Loss: 0.017476\n", + "Loss: 0.017475\n", + "Loss: 0.017398\n", + "Loss: 0.017352\n", + "Loss: 0.017329\n", + "Loss: 0.017298\n", + "Loss: 0.017278\n", + "Loss: 0.017254\n", + "Loss: 0.017230\n", + "Loss: 0.017218\n", + "Loss: 0.017217\n", + "Loss: 0.017193\n", + "Loss: 0.017185\n", + "Loss: 0.017085\n", + "Loss: 0.017070\n", + "Loss: 0.017053\n", + "Loss: 0.017034\n", + "Loss: 0.017011\n", + "Loss: 0.016996\n", + "Loss: 0.016972\n", + "Loss: 0.016970\n", + "Loss: 0.016897\n", + "Loss: 0.016894\n", + "Loss: 0.016867\n", + "Loss: 0.016854\n", + "Loss: 0.016829\n", + "Loss: 0.016798\n", + "Loss: 0.016778\n", + "Loss: 0.016756\n", + "Loss: 0.016740\n", + "Loss: 0.016726\n", + "Loss: 0.016702\n", + "Loss: 0.016682\n", + "Loss: 0.016652\n", + "Loss: 0.016633\n", + "Loss: 0.016603\n", + "Loss: 0.016589\n", + "Loss: 0.016570\n", + "Loss: 0.016542\n", + "Loss: 0.016522\n", + "Loss: 0.016504\n", + "Loss: 0.016502\n", + "Loss: 0.016456\n", + "Loss: 0.016420\n", + "Loss: 0.016401\n", + "Loss: 0.016398\n", + "Loss: 0.016374\n", + "Loss: 0.016332\n", + "Loss: 0.016325\n", + "Loss: 0.016264\n", + "Loss: 0.016243\n", + "Loss: 0.016236\n", + "Loss: 0.016225\n", + "Loss: 0.016183\n", + "Loss: 0.016167\n", + "Loss: 0.016148\n", + "Loss: 0.016135\n", + "Loss: 0.016128\n", + "Loss: 0.016117\n", + "Loss: 0.016056\n", + "Loss: 0.016029\n", + "Loss: 0.016008\n", + "Loss: 0.015994\n", + "Loss: 0.015972\n", + "Loss: 0.015972\n", + "Loss: 0.015937\n", + "Loss: 0.015904\n", + "Loss: 0.015897\n", + "Loss: 0.015865\n", + "Loss: 0.015843\n", + "Loss: 0.015868\n", + "Loss: 0.015892\n", + "Loss: 0.015850\n", + "Loss: 0.015838\n", + "Number of iterations: 500\n" + ] + } + ], + "source": [ + "theta_optimal=logistic_regression.fit()" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [], + "source": [ + "mu1 = -1\n", + "mu2 = 3\n", + "sig1 = 0.5\n", + "sig2 = 1\n", + "N = 2000\n", + "np.random.seed(10)\n", + "x11=np.random.randn(N,1)*sig1 + mu1\n", + "x12=np.random.randn(N,1)*sig1 + mu1+3\n", + "x21=np.random.randn(N,1)*sig2 + mu2\n", + "x22=np.random.randn(N,1)*sig2 + mu2+3\n", + "c = np.vstack((np.zeros((N,1)), np.ones((N,1))))\n", + "x1 = np.hstack((x11,x12))\n", + "x2 = np.hstack((x21,x22))\n", + "\n", + "X1 = np.hstack( (np.vstack( (x1,x2) ),c) )\n", + "np.random.shuffle(X)\n", + "#dataset = pd.DataFrame(data=X, columns=['x','y','c'])" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [], + "source": [ + "Features=X1[:,:-1]\n", + "Target=X1[:,-1]" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: 99.825 %\n" + ] + } + ], + "source": [ + "Accuraccy=(logistic_regression.predict(Features)==Target).sum()/len(Target)\n", + "print(\"Accuracy: {} %\".format(100*Accuraccy))" + ] + }, + { + "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.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}