# -*- coding: utf-8 -*-
"""LogisticRegression.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1Pymr8RvZdZkyufT_rl1nNGpH-1CkjNup

Same as linear Regression except , we pass the output through sigmoid activation function for classification
"""

import numpy as np

class LogisticRegression:

    def __init__(self , learning_rate = 0.001 , n_iters = 1000):
        self.learning_rate = learning_rate
        self.n_iters = n_iters
        self.weights = None
        self.bias = None
    
    def sigmoid_activation(self , x):
        return 1/(1+np.exp(-x))

    def fit(self , X , y):
        n_samples , n_features = X.shape

        #initializing weights and bias
        self.weights = np.zeros(n_features)
        self.bias = 0

        for i in range(n_samples):
            #applying approximation function for prediction
            linear_prediction = np.dot(X , self.weights)+self.bias

            #passing the output of logistic  regression model through a sigmoid function
            logistic_prediction = self.sigmoid_activation(linear_prediction)

            #calculating wwights and bias gradients (this tells the direction in which algo should proceed to reach the global minima)
            dw = (1/n_samples)*np.dot(2*X.T, (logistic_prediction - y))
            db = (1/n_samples) * 2*np.sum(logistic_prediction-y)

            #adjusting weights and bias
            self.weights -= self.learning_rate*dw
            self.bias -= self.learning_rate*db

    def predict(self , X):
        #applying approximation function for prediction
        linear_prediction = np.dot(X , self.weights)+self.bias

        #passing the output of logistic  regression model through a sigmoid function
        y_pred = self.sigmoid_activation(linear_prediction)

        classes = [1 if i > 0.5 else 0 for i in y_pred]

        return classes

from sklearn.model_selection import train_test_split
from sklearn import datasets

def accuracy(y_true, y_pred):
    accuracy = np.sum(y_true == y_pred) / len(y_true)
    return accuracy

bc = datasets.load_breast_cancer()
X, y = bc.data, bc.target

X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, random_state=1234
    )

regressor = LogisticRegression(learning_rate=0.0001, n_iters=1000)
regressor.fit(X_train, y_train)
predictions = regressor.predict(X_test)

print("LR classification accuracy:", accuracy(y_test, predictions))

from sklearn.metrics import confusion_matrix
y_true = y
y_pred = regressor.predict(X)
confusion_matrix(y_true, y_pred)

