-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
Copy pathlogistic_regression.py
70 lines (50 loc) · 1.85 KB
/
logistic_regression.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
"""
From scratch implementation of Logistic Regression
Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
* 2020-05-24 Initial coding
"""
import numpy as np
from sklearn.datasets import make_blobs
class LogisticRegression:
def __init__(self, X, learning_rate=0.1, num_iters=10000):
self.lr = learning_rate
self.num_iters = num_iters
# m for #training_examples, n for #features
self.m, self.n = X.shape
def train(self, X, y):
# init weights
self.weights = np.zeros((self.n, 1))
self.bias = 0
for it in range(self.num_iters + 1):
# calculate hypothesis
y_predict = self.sigmoid(np.dot(X, self.weights) + self.bias)
# calculate cost
cost = (
-1
/ self.m
* np.sum(y * np.log(y_predict) + (1 - y) * np.log(1 - y_predict))
)
# back prop / gradient calculations
dw = 1 / self.m * np.dot(X.T, (y_predict - y))
db = 1 / self.m * np.sum(y_predict - y)
# gradient descent update step
self.weights -= self.lr * dw
self.bias -= self.lr * db
# print cost sometimes
if it % 1000 == 0:
print(f"Cost after iteration {it}: {cost}")
return self.weights, self.bias
def predict(self, X):
y_predict = self.sigmoid(np.dot(X, self.weights) + self.bias)
y_predict_labels = y_predict > 0.5
return y_predict_labels
def sigmoid(self, z):
return 1 / (1 + np.exp(-z))
if __name__ == "__main__":
np.random.seed(1)
X, y = make_blobs(n_samples=1000, centers=2)
y = y[:, np.newaxis]
logreg = LogisticRegression(X)
w, b = logreg.train(X, y)
y_predict = logreg.predict(X)
print(f"Accuracy: {np.sum(y==y_predict)/X.shape[0]}")