In [1]:
    
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
    
In [27]:
    
data = pd.read_csv('ex2data1.txt', header=None, names=['exam1', 'exam2', 'admission'])
data.head()
    
    Out[27]:
In [28]:
    
def visualize(x, y, color):
    fig = plt.figure()
    ax = plt.axes()
    ax.scatter(x, y, c=color)
    plt.xlabel('exam1')
    plt.ylabel('exam2')
    plt.show()
visualize(data.exam1, data.exam2, data.admission)
    
    
adding a 'ones' vector to the matrix 'exam1'/'exam2'
In [29]:
    
vector = np.ones(100, dtype=float)
X = data.as_matrix(('exam1', 'exam2'))
X = np.c_[vector, X]
y = np.asarray(data.admission)
    
the sigmoid function for logistic regression and the predict function using the sigmoid
In [30]:
    
def sigmoid(z):
    return (1 / (1 + np.exp(-z)))
def predict(X, theta):
    return(sigmoid(np.dot(X, theta)))
    
the cost function associated with the model
In [31]:
    
def cost(X, y, theta):
    return((-1 / X.shape[0]) * np.sum(y * np.log(predict(X, theta)) + (1 - y) * np.log(1 - predict(X, theta))))
    
In [32]:
    
theta = np.zeros(3, dtype=float)
cost(X, y, theta)
    
    Out[32]:
In [35]:
    
def gradient_descent(X, y, theta, alpha, num_iters):
    m = X.shape[0]
    J_history = []
    for _ in range(num_iters):
        theta = theta - (alpha / m) * (np.dot(predict(X, theta) - y, X))
        J_history.append(cost(X, y, theta))
    return(theta, J_history)
    
training data with gradient descent (alpha 0.0011 and 4000000 iterations)
In [46]:
    
theta = np.zeros(3, dtype=float)
theta, J_history = gradient_descent(X, y, theta, 0.0011, 4000000)
    
In [52]:
    
cost(X, y, theta)
theta
    
    Out[52]:
Expected output: 0.20450663992202706
Visualizing the evolution of cost as iterations increases
In [48]:
    
fig = plt.figure()
ax = plt.axes()
ax.plot(J_history)
    
    Out[48]:
    
In [49]:
    
p = [1, 45, 85]
predict(p, theta)
    
    Out[49]:
In [50]:
    
r = predict(X, theta)
for i in range(r.shape[0]):
    if (r[i] > 0.5):
        r[i] = 1
    else:
        r[i] = 0
r
per = 0
for j in range(r.shape[0]):
    if (r[j] == y[j]):
        per += 1
per / 100
    
    Out[50]:
In [56]:
    
def visualize(x, y, color, theta):
    fig = plt.figure()
    ax = plt.axes()
    ax.scatter(x, y, c=color)
    plt.xlabel('exam1')
    plt.ylabel('exam2')
    plt.show()
visualize(data.exam1, data.exam2, data.admission, theta)
    
    
Expected output: 0.89