In [1]:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_circles

In [2]:
# generate two datasets
X,y = make_circles(n_samples = 3000, noise = 0.08, factor=0.3)
print(X.shape)
print(y.shape)
print(type(X))
print(type(y))

(3000, 2)
(3000,)
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>

In [3]:
# make a training and a test
X0 = []
X1 = []
for i in range(len(y)):
if y[i] == 0:
X0.append(X[i,:])
else:
X1.append(X[i,:])

X0_np = np.array(X0)
X1_np = np.array(X1)

X0_train = X0_np[:1000,:].T # we want X to be made of examples which are stacked horizontally that why we transpose
X0_test = X0_np[1000:,:].T
X1_train = X1_np[:1000,:].T
X1_test = X1_np[1000:,:].T

X_train = np.hstack([X0_train,X1_train]) # all training examples - from class 0 and from class 1
# the first 1000 examples are from class 0 (so they have lable 0)
y_train=np.zeros((1,2000))
# and the last 1000 are from class 1 (so they have label 1)
y_train[0, 1000:] = 1
X_test = np.hstack([X0_test,X1_test]) # all test examples - from class 0  and from class 1

# test set has 1000 examples, the first 500 are from calss 0 and the last 500 are from calss 1
y_test=np.zeros((1,1000))
y_test[0, 500:] = 1

# plot classes
plt.scatter(X0_train[0,:],X0_train[1,:], color = 'b', label = 'class 0 train')
plt.scatter(X1_train[0,:],X1_train[1,:], color = 'r',  label = 'class 1 train')
plt.scatter(X0_test[0,:],X0_test[1,:], color = 'LightBlue', label = 'class 0 test')
plt.scatter(X1_test[0,:],X1_test[1,:], color = 'Orange', label = 'class 1 test')
plt.xlabel('feature1')
plt.ylabel('feature2')
plt.legend()
plt.axis('equal')
plt.show()

# we will plot shapes of training and test set to make sure that they were made by stacking examoles horizontally
# so in every column of these matrices there is one examples
# in two rows there are features (feature1 is ploted on the x-axis, and feature2 is ploted on the y-axis)
print('Shape of X_train set is %i x %i.'%X_train.shape)
print('Shape of X_test set is %i x %i.'%X_test.shape)
# labels for these examples are in y_train and y_test
print('Shape of y_train set is %i x %i.'%y_train.shape)
print('Shape of y_test set is %i x %i.'%y_test.shape)

Shape of X_train set is 2 x 2000.
Shape of X_test set is 2 x 1000.
Shape of y_train set is 1 x 2000.
Shape of y_test set is 1 x 1000.

In [4]:
def sigmoid(z):
s=1/(1+np.exp(-z))
return s

In [5]:
def single_neuron(w, b, X, Y):

m = X.shape[1] # number of training examples

A = sigmoid(np.dot(w.T, X) + b)  # compute activations for all examples in the set
cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A)))  # compute cost

dw = (1 / m) * np.dot(X, (A - Y).T)
db = (1 / m) * np.sum(A - Y)

"db": db}


In [6]:
def optimize(w, b, X, Y, num_iterations, learning_rate):

costs = []

for i in range(num_iterations):

# we will repeate calculations that ocurre in a single neuron to provide our algorithm to learn parameters w and b
grads, cost = single_neuron(w, b, X, Y)

w = w - learning_rate * dw  # need to broadcast
b = b - learning_rate * db

# Record the costs
costs.append(cost)

# when for loop ends up we will save the final values of w and b in a dictionary
params = {"w": w,
"b": b}

return params, costs

In [7]:
# we need to initialize w and b
w = np.random.randn(X_train.shape[0],1)*0.01
b=0
param_w_b, costs = optimize(w, b, X_train, y_train, num_iterations= 10000, learning_rate = 0.09)

In [8]:
plt.plot(costs)
plt.xlabel('number of iterations')
plt.title('Cost function')

Out[8]:
Text(0.5,1,'Cost function')
In [9]:
# check the shape of parameters
# param_w_b is a dictionary which contains parameters w and b
# print shape of these parameters
print(param_w_b['w'].shape)
print(param_w_b['b'].shape)

(2, 1)
()

In [10]:
def make_predictions(w, b, X):

m = X.shape[1]
Y_predictions = np.zeros((1, m))

A = sigmoid(np.dot(w.T, X) + b)

for i in range(A.shape[1]):
Y_predictions[0, i] = 1 if A[0, i] > 0.5 else 0

assert(Y_predictions.shape == (1, m)) # assert is a way we care on matrix dimensions

return Y_predictions

In [11]:
# make predictions on both training set and test set
Y_predictions_train = make_predictions(param_w_b['w'], param_w_b['b'], X_train)
Y_predictions_test = make_predictions(param_w_b['w'], param_w_b['b'], X_test)

In [12]:
# make some plots to see how algorithm works on training set, so on examples that had been seen

plt.subplot(1,2,1)
plt.scatter(X0_train[0,:],X0_train[1,:], color = 'Blue', label = 'class 0 test')
plt.scatter(X1_train[0,:],X1_train[1,:], color = 'Red', label = 'class 1 test')
plt.xlabel('feature1')
plt.ylabel('feature2')
plt.title('Test set')
plt.axis('equal')

plt.subplot(1,2,2)
plt.scatter(X0_train[0,:],X0_train[1,:], color = 'Blue', label = 'class 0 test')
plt.scatter(X1_train[0,:],X1_train[1,:], color = 'Red', label = 'class 1 test')
for i in range(0,1000):
if Y_predictions_train[0,i] == 1 :
plt.scatter(X_train[0,i],X_train[1,i], color = 'Red')
for i in range(1000,2000):
if Y_predictions_train[0,i] == 0 :
plt.scatter(X_train[0,i],X_train[1,i], color = 'Blue')

plt.xlabel('feature1')
plt.title('Classified')
plt.axis('equal')
plt.show()

# print the accuracy on the training set
print("train accuracy: {} %".format(100 - np.mean(np.abs(Y_predictions_train - y_train)) * 100))

train accuracy: 49.85000000000001 %

In [13]:
# make some plots to see how algorithm works on unseen data

plt.subplot(1,2,1)
plt.scatter(X0_test[0,:],X0_test[1,:], color = 'LightBlue', label = 'class 0 test')
plt.scatter(X1_test[0,:],X1_test[1,:], color = 'Orange', label = 'class 1 test')
plt.ylabel('feature2')
plt.xlabel('feature1')
plt.title('Test set')
plt.axis('equal')

plt.subplot(1,2,2)
plt.scatter(X0_test[0,:],X0_test[1,:], color = 'LightBlue', label = 'class 0 test')
plt.scatter(X1_test[0,:],X1_test[1,:], color = 'Orange', label = 'class 1 test')
for i in range(0,500):
if Y_predictions_test[0,i] == 1 :
plt.scatter(X_test[0,i],X_test[1,i], color = 'Orange')
for i in range(500,1000):
if Y_predictions_test[0,i] == 0 :
plt.scatter(X_test[0,i],X_test[1,i], color = 'LightBlue')

plt.xlabel('feature1')
plt.axis('equal')
plt.title('Classified')
plt.show()

print("test accuracy: {} %".format(100 - np.mean(np.abs(Y_predictions_test - y_test)) * 100))

test accuracy: 49.7 %