Logistic Regression¶
In [1]:
Copied!
# Uncomment the next line and run this cell to install sorix
#!pip install 'sorix @ git+https://github.com/Mitchell-Mirano/sorix.git@main'
# Uncomment the next line and run this cell to install sorix
#!pip install 'sorix @ git+https://github.com/Mitchell-Mirano/sorix.git@main'
In [2]:
Copied!
import os
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
import os
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
In [3]:
Copied!
import sorix
from sorix.model_selection import train_test_split
from sorix.metrics import classification_report, confusion_matrix
from sorix.nn import Linear, BCEWithLogitsLoss
from sorix.optim import RMSprop, Adam
import sorix
from sorix.model_selection import train_test_split
from sorix.metrics import classification_report, confusion_matrix
from sorix.nn import Linear, BCEWithLogitsLoss
from sorix.optim import RMSprop, Adam
In [4]:
Copied!
device = 'cuda' if sorix.cuda.is_available() else 'cpu'
device
device = 'cuda' if sorix.cuda.is_available() else 'cpu'
device
✅ GPU basic operation passed ✅ GPU available: NVIDIA GeForce RTX 4070 Laptop GPU CUDA runtime version: 13000 CuPy version: 13.6.0
Out[4]:
'cuda'
In [5]:
Copied!
data=pd.read_csv("../data/Iris.csv")
data.head()
data=pd.read_csv("../data/Iris.csv")
data.head()
Out[5]:
| Id | SepalLengthCm | SepalWidthCm | PetalLengthCm | PetalWidthCm | Species | |
|---|---|---|---|---|---|---|
| 0 | 1 | 5.1 | 3.5 | 1.4 | 0.2 | Iris-setosa |
| 1 | 2 | 4.9 | 3.0 | 1.4 | 0.2 | Iris-setosa |
| 2 | 3 | 4.7 | 3.2 | 1.3 | 0.2 | Iris-setosa |
| 3 | 4 | 4.6 | 3.1 | 1.5 | 0.2 | Iris-setosa |
| 4 | 5 | 5.0 | 3.6 | 1.4 | 0.2 | Iris-setosa |
In [6]:
Copied!
data['Species'].unique()
data = data[data['Species'].isin(['Iris-setosa', 'Iris-versicolor'])]
data
data['Species'].unique()
data = data[data['Species'].isin(['Iris-setosa', 'Iris-versicolor'])]
data
Out[6]:
| Id | SepalLengthCm | SepalWidthCm | PetalLengthCm | PetalWidthCm | Species | |
|---|---|---|---|---|---|---|
| 0 | 1 | 5.1 | 3.5 | 1.4 | 0.2 | Iris-setosa |
| 1 | 2 | 4.9 | 3.0 | 1.4 | 0.2 | Iris-setosa |
| 2 | 3 | 4.7 | 3.2 | 1.3 | 0.2 | Iris-setosa |
| 3 | 4 | 4.6 | 3.1 | 1.5 | 0.2 | Iris-setosa |
| 4 | 5 | 5.0 | 3.6 | 1.4 | 0.2 | Iris-setosa |
| ... | ... | ... | ... | ... | ... | ... |
| 95 | 96 | 5.7 | 3.0 | 4.2 | 1.2 | Iris-versicolor |
| 96 | 97 | 5.7 | 2.9 | 4.2 | 1.3 | Iris-versicolor |
| 97 | 98 | 6.2 | 2.9 | 4.3 | 1.3 | Iris-versicolor |
| 98 | 99 | 5.1 | 2.5 | 3.0 | 1.1 | Iris-versicolor |
| 99 | 100 | 5.7 | 2.8 | 4.1 | 1.3 | Iris-versicolor |
100 rows × 6 columns
In [7]:
Copied!
labels2id = {label: i for i, label in enumerate(data['Species'].unique())}
id2labels = {i: label for i, label in enumerate(data['Species'].unique())}
labels2id = {label: i for i, label in enumerate(data['Species'].unique())}
id2labels = {i: label for i, label in enumerate(data['Species'].unique())}
In [8]:
Copied!
data['labels']=data['Species'].map(labels2id)
data = data[data['labels'].isin([0,1])]
data.head()
data['labels']=data['Species'].map(labels2id)
data = data[data['labels'].isin([0,1])]
data.head()
Out[8]:
| Id | SepalLengthCm | SepalWidthCm | PetalLengthCm | PetalWidthCm | Species | labels | |
|---|---|---|---|---|---|---|---|
| 0 | 1 | 5.1 | 3.5 | 1.4 | 0.2 | Iris-setosa | 0 |
| 1 | 2 | 4.9 | 3.0 | 1.4 | 0.2 | Iris-setosa | 0 |
| 2 | 3 | 4.7 | 3.2 | 1.3 | 0.2 | Iris-setosa | 0 |
| 3 | 4 | 4.6 | 3.1 | 1.5 | 0.2 | Iris-setosa | 0 |
| 4 | 5 | 5.0 | 3.6 | 1.4 | 0.2 | Iris-setosa | 0 |
In [9]:
Copied!
plt.figure(figsize=(10,6))
for specie in data['Species'].unique():
specie_data = data[data['Species'] == specie]
plt.scatter(specie_data['PetalLengthCm'],specie_data['SepalWidthCm'],s=80 ,label=specie )
plt.legend()
plt.xlabel("Petal Length")
plt.ylabel("Sepal Width")
plt.figure(figsize=(10,6))
for specie in data['Species'].unique():
specie_data = data[data['Species'] == specie]
plt.scatter(specie_data['PetalLengthCm'],specie_data['SepalWidthCm'],s=80 ,label=specie )
plt.legend()
plt.xlabel("Petal Length")
plt.ylabel("Sepal Width")
In [10]:
Copied!
independent_features=['PetalLengthCm','SepalWidthCm','PetalWidthCm','SepalLengthCm']
dependent_feature=['labels']
independent_features=['PetalLengthCm','SepalWidthCm','PetalWidthCm','SepalLengthCm']
dependent_feature=['labels']
In [11]:
Copied!
data_train,data_test=train_test_split(data,test_size=0.2)
X_train=sorix.tensor(data_train[independent_features],device=device)
Y_train=sorix.tensor(data_train[dependent_feature],device=device)
X_test=sorix.tensor(data_test[independent_features],device=device)
Y_test=sorix.tensor(data_test[dependent_feature],device=device)
X_train.shape,Y_train.shape,X_test.shape,Y_test.shape
data_train,data_test=train_test_split(data,test_size=0.2)
X_train=sorix.tensor(data_train[independent_features],device=device)
Y_train=sorix.tensor(data_train[dependent_feature],device=device)
X_test=sorix.tensor(data_test[independent_features],device=device)
Y_test=sorix.tensor(data_test[dependent_feature],device=device)
X_train.shape,Y_train.shape,X_test.shape,Y_test.shape
Out[11]:
(sorix.Size([80, 4]), sorix.Size([80, 1]), sorix.Size([20, 4]), sorix.Size([20, 1]))
In [12]:
Copied!
model = Linear(4, 1).to(device)
loss_fn = BCEWithLogitsLoss()
optimizer = Adam(model.parameters(), lr=0.01)
model = Linear(4, 1).to(device)
loss_fn = BCEWithLogitsLoss()
optimizer = Adam(model.parameters(), lr=0.01)
In [13]:
Copied!
for epoch in range(1000+1):
y_pred = model(X_train)
loss = loss_fn(y_pred, Y_train)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 100 == 0:
print(f"Epoch: {epoch} | Loss: {loss.item():.4f}")
for epoch in range(1000+1):
y_pred = model(X_train)
loss = loss_fn(y_pred, Y_train)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if epoch % 100 == 0:
print(f"Epoch: {epoch} | Loss: {loss.item():.4f}")
Epoch: 0 | Loss: 1.6742 Epoch: 100 | Loss: 0.2143 Epoch: 200 | Loss: 0.1048 Epoch: 300 | Loss: 0.0634
Epoch: 400 | Loss: 0.0433 Epoch: 500 | Loss: 0.0319 Epoch: 600 | Loss: 0.0247 Epoch: 700 | Loss: 0.0198
Epoch: 800 | Loss: 0.0163 Epoch: 900 | Loss: 0.0137 Epoch: 1000 | Loss: 0.0117
In [14]:
Copied!
with sorix.no_grad():
logits = model(X_test)
probs = sorix.sigmoid(logits)
preds = (probs > 0.5).astype('uint8')
acc_test = (preds == Y_test).mean()
plt.scatter(X_test[:,0],X_test[:,1],c=preds)
plt.title(f"Logistic Regression on Test Data(Accuracy:{100*acc_test.item():.2f}%)")
plt.show()
with sorix.no_grad():
logits = model(X_test)
probs = sorix.sigmoid(logits)
preds = (probs > 0.5).astype('uint8')
acc_test = (preds == Y_test).mean()
plt.scatter(X_test[:,0],X_test[:,1],c=preds)
plt.title(f"Logistic Regression on Test Data(Accuracy:{100*acc_test.item():.2f}%)")
plt.show()
Save Model¶
In [15]:
Copied!
sorix.save(model.state_dict(),"logistic_model.sor")
sorix.save(model.state_dict(),"logistic_model.sor")
In [16]:
Copied!
model2 = Linear(4, 1)
model2.load_state_dict(sorix.load("logistic_model.sor"))
model2.to(device)
model2 = Linear(4, 1)
model2.load_state_dict(sorix.load("logistic_model.sor"))
model2.to(device)
Out[16]:
Linear(in_features=4, out_features=1, bias=True)
In [17]:
Copied!
with sorix.no_grad():
logits = model2(X_test)
probs = sorix.sigmoid(logits)
preds = (probs.data > 0.5).astype('uint8')
acc_test = (preds == Y_test.data).mean()
preds = preds.get() if device == 'cuda' else preds
plt.scatter(X_test[:,0],X_test[:,1],c=preds)
plt.title(f"Logistic Regression on Test Data(Accuracy:{100*acc_test:.2f}%)")
plt.show()
with sorix.no_grad():
logits = model2(X_test)
probs = sorix.sigmoid(logits)
preds = (probs.data > 0.5).astype('uint8')
acc_test = (preds == Y_test.data).mean()
preds = preds.get() if device == 'cuda' else preds
plt.scatter(X_test[:,0],X_test[:,1],c=preds)
plt.title(f"Logistic Regression on Test Data(Accuracy:{100*acc_test:.2f}%)")
plt.show()