Galle, LK--:--5/6 sites live

Implementing Logistic Regression from scratch in Python

කලින් පාඩමේ sigmoid maths එක, මෙතන වැඩ කරන code එකක් වෙනවා — scikit-learn version එකෙන් එන ම වගේ probability output එකක් මෙතනින් එනවා ඔයාට පේනවා.

The sigmoid math from the last lesson becomes working code here — and you'll see it produce the same kind of probability output scikit-learn's version does.

13 May 20266 min readSelf Guide · Stage 15#Building Models from Scratch#Algorithms from Scratch#Machine learning

Lesson 36 of 64 · Part 3 · Building Models from Scratch · Algorithms from Scratch · bilingual notes (English + සිංහල)

Why this matters. The sigmoid math from the last lesson becomes working code here — and you'll see it produce the same kind of probability output scikit-learn's version does.

සිංහලෙන්: කලින් පාඩමේ sigmoid maths එක, මෙතන වැඩ කරන code එකක් වෙනවා — scikit-learn version එකෙන් එන ම වගේ probability output එකක් මෙතනින් එනවා ඔයාට පේනවා.

What you'll use this for. This is the exact confidence score behind "this email is 92% likely spam" style predictions you've already used.

සිංහලෙන්: දැනටමත් පාවිච්චි කරපු "මේ email 92% likely spam" වගේ predictions වල confidence score එකයි මේකෙන් එන්නෙ.

Key principles

  • Cross-entropy loss punishes confident wrong answers much more than uncertain ones. Being 99% sure of the wrong class costs the model far more than being 51% sure — this is what pushes it toward well-calibrated, honest probabilities.
    Cross-entropy loss, uncertain answers වලට වඩා confident වැරදි answers දඩුවම් කරනවා

Walkthrough

Logistic Regression:

Picture4.png

Y_hat --> predicted value

X --> Input Variable

w --> weight

b --> bias

Gradient Descent:

Gradient Descent is an optimization algorithm used for minimizing the loss function in various machine learning algorithms. It is used for updating the parameters of the learning model.

w = w - α*dw

b = b - α*db

Learning Rate:

Learning rate is a tuning parameter in an optimization algorithm that determines the step size at each iteration while moving toward a minimum of a loss function.

Derivatives:

Picture3.png

Importing the Dependencies

ExamplePython
# importing numpy library
import numpy as np

Logistic Regression

ExamplePython
class Logistic_Regression():

  # declaring learning rate & number of iterations (Hyperparametes)
  def __init__(self, learning_rate, no_of_iterations):

    self.learning_rate = learning_rate
    self.no_of_iterations = no_of_iterations

  # fit function to train the model with dataset
  def fit(self, X, Y):

    # number of data points in the dataset (number of rows)  -->  m
    # number of input features in the dataset (number of columns)  --> n
    self.m, self.n = X.shape

    #initiating weight & bias value

    self.w = np.zeros(self.n)
    
    self.b = 0

    self.X = X

    self.Y = Y

    # implementing Gradient Descent for Optimization

    for i in range(self.no_of_iterations):     
      self.update_weights()

  def update_weights(self):

    # Y_hat formula (sigmoid function)

    Y_hat = 1 / (1 + np.exp( - (self.X.dot(self.w) + self.b ) ))    

    # derivaties

    dw = (1/self.m)*np.dot(self.X.T, (Y_hat - self.Y))

    db = (1/self.m)*np.sum(Y_hat - self.Y)

    # updating the weights & bias using gradient descent

    self.w = self.w - self.learning_rate * dw

    self.b = self.b - self.learning_rate * db

  # Sigmoid Equation & Decision Boundary

  def predict(self, X):

    Y_pred = 1 / (1 + np.exp( - (X.dot(self.w) + self.b ) ))     
    Y_pred = np.where( Y_pred > 0.5, 1, 0)
    return Y_pred

Importing the Dependencies

ExamplePython
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

Data Collection and Analysis

PIMA Diabetes Dataset

ExamplePython
# loading the diabetes dataset to a pandas DataFrame
diabetes_dataset = pd.read_csv('/content/diabetes.csv')
ExamplePython
# printing the first 5 rows of the dataset
diabetes_dataset.head()
PregnanciesGlucoseBloodPressureSkinThicknessInsulinBMIDiabetesPedigreeFunction…
061487235033.60.627…
11856629026.60.351…
28183640023.30.672…
318966239428.10.167…
40137403516843.12.288…
ExamplePython
# number of rows and Columns in this dataset
diabetes_dataset.shape

Output

Output
(768, 9)
ExamplePython
# getting the statistical measures of the data
diabetes_dataset.describe()
PregnanciesGlucoseBloodPressureSkinThicknessInsulinBMIDiabetesPedigreeFunction…
count768.000000768.000000768.000000768.000000768.000000768.000000768.000000…
mean3.845052120.89453169.10546920.53645879.79947931.9925780.471876…
std3.36957831.97261819.35580715.952218115.2440027.8841600.331329…
min0.0000000.0000000.0000000.0000000.0000000.0000000.078000…
25%1.00000099.00000062.0000000.0000000.00000027.3000000.243750…
50%3.000000117.00000072.00000023.00000030.50000032.0000000.372500…

… 2 more rows

ExamplePython
diabetes_dataset['Outcome'].value_counts()

Output

Output
0    500
1    268
Name: Outcome, dtype: int64

0 --> Non-Diabetic

1 --> Diabetic

ExamplePython
diabetes_dataset.groupby('Outcome').mean()
PregnanciesGlucoseBloodPressureSkinThicknessInsulinBMIDiabetesPedigreeFunctionAge
Outcome
03.298000109.98000068.18400019.66400068.79200030.3042000.42973431.190000
14.865672141.25746370.82462722.164179100.33582135.1425370.55050037.067164
ExamplePython
# separating the data and labels
features = diabetes_dataset.drop(columns = 'Outcome', axis=1)
target = diabetes_dataset['Outcome']
ExamplePython
print(features)

Output

Output
     Pregnancies  Glucose  BloodPressure  ...   BMI  DiabetesPedigreeFunction  Age
0              6      148             72  ...  33.6                     0.627   50
1              1       85             66  ...  26.6                     0.351   31
2              8      183             64  ...  23.3                     0.672   32
3              1       89             66  ...  28.1                     0.167   21
4              0      137             40  ...  43.1                     2.288   33
..           ...      ...            ...  ...   ...                       ...  ...
763           10      101             76  ...  32.9                     0.171   63
764            2      122             70  ...  36.8                     0.340   27
765            5      121             72  ...  26.2                     0.245   30
766            1      126             60  ...  30.1                     0.349   47
767            1       93             70  ...  30.4                     0.315   23

[768 rows x 8 columns]
ExamplePython
print(target)

Output

Output
0      1
1      0
2      1
3      0
4      1
      ..
763    0
764    0
765    0
766    1
767    0
Name: Outcome, Length: 768, dtype: int64

Data Standardization

ExamplePython
scaler = StandardScaler()
ExamplePython
scaler.fit(features)

Output

Output
StandardScaler(copy=True, with_mean=True, with_std=True)
ExamplePython
standardized_data = scaler.transform(features)
ExamplePython
print(standardized_data)

Output

Output
[[ 0.63994726  0.84832379  0.14964075 ...  0.20401277  0.46849198
   1.4259954 ]
 [-0.84488505 -1.12339636 -0.16054575 ... -0.68442195 -0.36506078
  -0.19067191]
 [ 1.23388019  1.94372388 -0.26394125 ... -1.10325546  0.60439732
  -0.10558415]
 ...
 [ 0.3429808   0.00330087  0.14964075 ... -0.73518964 -0.68519336
  -0.27575966]
 [-0.84488505  0.1597866  -0.47073225 ... -0.24020459 -0.37110101
   1.17073215]
 [-0.84488505 -0.8730192   0.04624525 ... -0.20212881 -0.47378505
  -0.87137393]]
ExamplePython
features = standardized_data
target = diabetes_dataset['Outcome']
ExamplePython
print(features)
print(target)

Output

Output
[[ 0.63994726  0.84832379  0.14964075 ...  0.20401277  0.46849198
   1.4259954 ]
 [-0.84488505 -1.12339636 -0.16054575 ... -0.68442195 -0.36506078
  -0.19067191]
 [ 1.23388019  1.94372388 -0.26394125 ... -1.10325546  0.60439732
  -0.10558415]
 ...
 [ 0.3429808   0.00330087  0.14964075 ... -0.73518964 -0.68519336
  -0.27575966]
 [-0.84488505  0.1597866  -0.47073225 ... -0.24020459 -0.37110101
   1.17073215]
 [-0.84488505 -0.8730192   0.04624525 ... -0.20212881 -0.47378505
  -0.87137393]]
0      1
1      0
2      1
3      0
4      1
… (7 more lines)

Train Test Split

ExamplePython
X_train, X_test, Y_train, Y_test = train_test_split(features,target, test_size = 0.2, random_state=2)
ExamplePython
print(features.shape, X_train.shape, X_test.shape)

Output

Output
(768, 8) (614, 8) (154, 8)

Training the Model

ExamplePython
classifier = Logistic_Regression(learning_rate=0.01, no_of_iterations=1000)
ExamplePython
#training the support vector Machine Classifier
classifier.fit(X_train, Y_train)

Model Evaluation

Accuracy Score

ExamplePython
# accuracy score on the training data
X_train_prediction = classifier.predict(X_train)
training_data_accuracy = accuracy_score( Y_train, X_train_prediction)
ExamplePython
print('Accuracy score of the training data : ', training_data_accuracy)

Output

Output
Accuracy score of the training data :  0.7768729641693811
ExamplePython
# accuracy score on the test data
X_test_prediction = classifier.predict(X_test)
test_data_accuracy = accuracy_score( Y_test, X_test_prediction)
ExamplePython
print('Accuracy score of the test data : ', test_data_accuracy)

Output

Output
Accuracy score of the test data :  0.7662337662337663

Making a Predictive System

ExamplePython
input_data = (5,166,72,19,175,25.8,0.587,51)

# changing the input_data to numpy array
input_data_as_numpy_array = np.asarray(input_data)

# reshape the array as we are predicting for one instance
input_data_reshaped = input_data_as_numpy_array.reshape(1,-1)

# standardize the input data
std_data = scaler.transform(input_data_reshaped)
print(std_data)

prediction = classifier.predict(std_data)
print(prediction)

if (prediction[0] == 0):
  print('The person is not diabetic')
else:
  print('The person is diabetic')

Output

Output
[[ 0.3429808   1.41167241  0.14964075 -0.09637905  0.82661621 -0.78595734
   0.34768723  1.51108316]]
[1]
The person is diabetic

Keep going: ← Lesson 35 · Lesson 37 → · Track it in the Self Guide