In [1]:
# Useful starting lines
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
%load_ext autoreload
%autoreload 2
In [2]:
from helpers import sample_data, load_data, standardize
# load data.
height, weight, gender = load_data()
# build sampled x and y.
seed = 1
y = np.expand_dims(gender, axis=1)
X = np.c_[height.reshape(-1), weight.reshape(-1)]
y, X = sample_data(y, X, seed, size_samples=200)
x, mean_x, std_x = standardize(X)
Use least_squares
to compute w, and visualize the results.
In [4]:
from least_squares import least_squares
from plots import visualization
def least_square_classification_demo(y, x):
# classify the data by linear regression
tx = np.c_[np.ones((y.shape[0], 1)), x]
w = least_squares(y, tx)
# visualize your classification.
visualization(y, x, mean_x, std_x, w, "classification_by_least_square")
least_square_classification_demo(y, x)
Compute your cost by negative log likelihood.
In [70]:
def sigmoid(t):
"""apply sigmoid function on t."""
return 1.0 / (1 + np.exp(-t))
In [71]:
def calculate_loss(y, tx, w):
"""compute the cost by negative log likelihood."""
pred = sigmoid(tx.dot(w))
loss = y.T.dot(np.log(pred)) + (1 - y).T.dot(np.log(1 - pred))
return np.squeeze(- loss)
In [72]:
def calculate_gradient(y, tx, w):
"""compute the gradient of loss."""
pred = sigmoid(tx.dot(w))
grad = tx.T.dot(pred - y)
return grad
In [73]:
def learning_by_gradient_descent(y, tx, w, gamma):
"""
Do one step of gradient descen using logistic regression.
Return the loss and the updated w.
"""
loss = calculate_loss(y, tx, w)
grad = calculate_gradient(y, tx, w)
w -= gamma * grad
return loss, w
Demo!
In [74]:
from helpers import de_standardize
def logistic_regression_gradient_descent_demo(y, x):
# init parameters
max_iter = 10000
threshold = 1e-8
gamma = 0.01
losses = []
# build tx
tx = np.c_[np.ones((y.shape[0], 1)), x]
w = np.zeros((tx.shape[1], 1))
# start the logistic regression
for iter in range(max_iter):
# get loss and update w.
loss, w = learning_by_gradient_descent(y, tx, w, gamma)
# log info
if iter % 100 == 0:
print("Current iteration={i}, loss={l}".format(i=iter, l=loss))
# converge criterion
losses.append(loss)
if len(losses) > 1 and np.abs(losses[-1] - losses[-2]) < threshold:
break
# visualization
visualization(y, x, mean_x, std_x, w, "classification_by_logistic_regression_gradient_descent")
print("loss={l}".format(l=calculate_loss(y, tx, w)))
logistic_regression_gradient_descent_demo(y, x)
Calculate your hessian below
In [75]:
def calculate_hessian(y, tx, w):
"""return the hessian of the loss function."""
pred = sigmoid(tx.dot(w))
pred = np.diag(pred.T[0])
r = np.multiply(pred, (1-pred))
return tx.T.dot(r).dot(tx)
Write a function below to return loss, gradient, and hessian.
In [76]:
def logistic_regression(y, tx, w):
"""return the loss, gradient, and hessian."""
loss = calculate_loss(y, tx, w)
gradient = calculate_gradient(y, tx, w)
hessian = calculate_hessian(y, tx, w)
return loss, gradient, hessian
In [77]:
def learning_by_newton_method(y, tx, w):
"""
Do one step on Newton's method.
return the loss and updated w.
"""
loss, gradient, hessian = logistic_regression(y, tx, w)
w -= np.linalg.solve(hessian, gradient)
return loss, w
demo
In [78]:
def logistic_regression_newton_method_demo(y, x):
# init parameters
max_iter = 100
threshold = 1e-8
lambda_ = 0.1
losses = []
# build tx
tx = np.c_[np.ones((y.shape[0], 1)), x]
w = np.zeros((tx.shape[1], 1))
# start the logistic regression
for iter in range(max_iter):
# get loss and update w.
loss, w = learning_by_newton_method(y, tx, w)
# log info
if iter % 1 == 0:
print("Current iteration={i}, the loss={l}".format(i=iter, l=loss))
# converge criterion
losses.append(loss)
if len(losses) > 1 and np.abs(losses[-1] - losses[-2]) < threshold:
break
# visualization
visualization(y, x, mean_x, std_x, w, "classification_by_logistic_regression_newton_method")
print("loss={l}".format(l=calculate_loss(y, tx, w)))
logistic_regression_newton_method_demo(y, x)
In [82]:
def penalized_logistic_regression(y, tx, w, lambda_):
"""return the loss and gradient."""
num_samples = y.shape[0]
loss = calculate_loss(y, tx, w) + lambda_ * np.squeeze(w.T.dot(w))
gradient = calculate_gradient(y, tx, w) + 2 * lambda_ * w
return loss, gradient
In [83]:
def learning_by_penalized_gradient(y, tx, w, gamma, lambda_):
"""
Do one step of gradient descent, using the penalized logistic regression.
Return the loss and updated w.
"""
loss, gradient = penalized_logistic_regression(y, tx, w, lambda_)
w -= gamma * gradient
return loss, w
In [86]:
def logistic_regression_penalized_gradient_descent_demo(y, x):
# init parameters
max_iter = 10000
gamma = 0.01
lambda_ = 0.1
threshold = 1e-8
losses = []
# build tx
tx = np.c_[np.ones((y.shape[0], 1)), x]
w = np.zeros((tx.shape[1], 1))
# start the logistic regression
for iter in range(max_iter):
# get loss and update w.
loss, w = learning_by_penalized_gradient(y, tx, w, gamma, lambda_)
# log info
if iter % 100 == 0:
print("Current iteration={i}, loss={l}".format(i=iter, l=loss))
# converge criterion
losses.append(loss)
if len(losses) > 1 and np.abs(losses[-1] - losses[-2]) < threshold:
break
# visualization
visualization(y, x, mean_x, std_x, w, "classification_by_logistic_regression_penalized_gradient_descent")
print("loss={l}".format(l=calculate_loss(y, tx, w)))
logistic_regression_penalized_gradient_descent_demo(y, x)
In [ ]: