Perceptron
Perceptron¶


In [1]:
Copied!
import numpy as np
import pandas as pd
import numpy as np
import pandas as pd
1. Data preparation¶
In [2]:
Copied!
def prepare_data(csv):
# Getting data ready
data = pd.read_csv(csv)
# Data normalisation
data['Age'] = data['Age'] / 100
# z-score normalisation
data['Income'] = (data['Income'] - data['Income'].mean()) / data['Income'].std()
data['Previous Purchases'] = (data['Previous Purchases'] - data['Previous Purchases'].mean()) / data['Previous Purchases'].std()
return data
def prepare_data(csv):
# Getting data ready
data = pd.read_csv(csv)
# Data normalisation
data['Age'] = data['Age'] / 100
# z-score normalisation
data['Income'] = (data['Income'] - data['Income'].mean()) / data['Income'].std()
data['Previous Purchases'] = (data['Previous Purchases'] - data['Previous Purchases'].mean()) / data['Previous Purchases'].std()
return data
2. Setting up the perceptron¶
In [3]:
Copied!
def prepare_matrices(data):
# Prepare input matrix and prediction matrix
X = []
Y = []
for idx, rows in data.iterrows():
x, y = rows.iloc[:-1].to_numpy(), rows.iloc[-1]
X.append(x)
Y.append(y)
X = np.array(X)
Y = np.array(Y)
return X, Y
def prepare_matrices(data):
# Prepare input matrix and prediction matrix
X = []
Y = []
for idx, rows in data.iterrows():
x, y = rows.iloc[:-1].to_numpy(), rows.iloc[-1]
X.append(x)
Y.append(y)
X = np.array(X)
Y = np.array(Y)
return X, Y
In [4]:
Copied!
def get_weights_bias(input_size):
# Init weights
W = np.random.rand(input_size)
# init weights
b = np.random.rand(1)
return W, b
def get_weights_bias(input_size):
# Init weights
W = np.random.rand(input_size)
# init weights
b = np.random.rand(1)
return W, b
In [7]:
Copied!
data = prepare_data('../data/purchase_prediction.csv')
X, Y = prepare_matrices(data)
W, b = get_weights_bias(X.shape[1])
data = prepare_data('../data/purchase_prediction.csv')
X, Y = prepare_matrices(data)
W, b = get_weights_bias(X.shape[1])
3. Training¶
In [8]:
Copied!
# Sigmoid activation
def sigmoid(H):
return 1 / (1 + np.exp(-H))
# BCE
def cross_entropy(y, y_pred):
y_pred = np.clip(y_pred, 1e-9, 1 - 1e-9)
return -np.sum(y*np.log(y_pred) + (1-y)*np.log(1-y_pred)) / len(y)
# BCE grad
def cross_entropy_grad(y, y_pred):
return -np.mean((y/y_pred) + ((1-y)/(1-y_pred)))
# Sigmoid activation
def sigmoid(H):
return 1 / (1 + np.exp(-H))
# BCE
def cross_entropy(y, y_pred):
y_pred = np.clip(y_pred, 1e-9, 1 - 1e-9)
return -np.sum(y*np.log(y_pred) + (1-y)*np.log(1-y_pred)) / len(y)
# BCE grad
def cross_entropy_grad(y, y_pred):
return -np.mean((y/y_pred) + ((1-y)/(1-y_pred)))
In [9]:
Copied!
epochs = 100000
lr = 0.01
print_after = 10000
for epoch in range(1, epochs+1):
###
# feed forward
# sum
H = np.matmul(X, W) + b
# activation
A = sigmoid(H)
# calc binary cross entropy loss
loss = cross_entropy(Y, A)
###
# backpropagate
dz = A - Y
dw = (1/len(Y)) * np.matmul(X.T, dz)
db = (1/len(Y)) * np.sum(dz)
# update weights
W = W - lr*dw
b = b - lr*db
if epoch % print_after == 0:
print(f"Epoch: {epoch}/{epochs}| Loss: {loss}")
epochs = 100000
lr = 0.01
print_after = 10000
for epoch in range(1, epochs+1):
###
# feed forward
# sum
H = np.matmul(X, W) + b
# activation
A = sigmoid(H)
# calc binary cross entropy loss
loss = cross_entropy(Y, A)
###
# backpropagate
dz = A - Y
dw = (1/len(Y)) * np.matmul(X.T, dz)
db = (1/len(Y)) * np.sum(dz)
# update weights
W = W - lr*dw
b = b - lr*db
if epoch % print_after == 0:
print(f"Epoch: {epoch}/{epochs}| Loss: {loss}")
Epoch: 10000/100000| Loss: 0.14486881031094775 Epoch: 20000/100000| Loss: 0.12188557399732414 Epoch: 30000/100000| Loss: 0.10799112930053398 Epoch: 40000/100000| Loss: 0.09740161380919043 Epoch: 50000/100000| Loss: 0.08875526442831948 Epoch: 60000/100000| Loss: 0.08147343673857062 Epoch: 70000/100000| Loss: 0.0752295171311487 Epoch: 80000/100000| Loss: 0.06980930346019368 Epoch: 90000/100000| Loss: 0.06505985371220571 Epoch: 100000/100000| Loss: 0.060866222059249894
Testing¶
In [11]:
Copied!
x_1 = np.array([0.32, 0.671181, 0.493606])
x_2 = np.array([0.48, -0.979264, -0.211545])
def predict(input_x):
H = np.matmul(input_x, W)
A = sigmoid(H)
print(A)
if A > 0.5:
print(1)
else:
print(0)
predict(x_1) # 1
predict(x_2) # 0
x_1 = np.array([0.32, 0.671181, 0.493606])
x_2 = np.array([0.48, -0.979264, -0.211545])
def predict(input_x):
H = np.matmul(input_x, W)
A = sigmoid(H)
print(A)
if A > 0.5:
print(1)
else:
print(0)
predict(x_1) # 1
predict(x_2) # 0
0.9968600634790575 1 0.0006271349965844889 0
In [12]:
Copied!
data
data
Out[12]:
| Age | Income | Previous Purchases | Purchased | |
|---|---|---|---|---|
| 0 | 0.25 | -0.429116 | -0.916696 | 0 |
| 1 | 0.32 | 0.671181 | 0.493606 | 1 |
| 2 | 0.48 | -0.979264 | -0.211545 | 0 |
| 3 | 0.18 | -1.254339 | -0.916696 | 0 |
| 4 | 0.65 | 1.771478 | 1.198756 | 1 |
| 5 | 0.42 | 0.396107 | -0.916696 | 0 |
| 6 | 0.28 | -0.539146 | -0.211545 | 1 |
| 7 | 0.55 | 1.221330 | 1.903907 | 1 |
| 8 | 0.35 | 0.011003 | 0.493606 | 1 |
| 9 | 0.22 | -0.869235 | -0.916696 | 0 |
In [ ]:
Copied!