First commit

This commit is contained in:
Dib, Gerges
2018-02-23 17:16:58 -08:00
commit 1239a1d937
92 changed files with 14734 additions and 0 deletions

Binary file not shown.

BIN
Exercise8/Data/ex8_movies.mat Executable file

Binary file not shown.

BIN
Exercise8/Data/ex8data1.mat Executable file

Binary file not shown.

BIN
Exercise8/Data/ex8data2.mat Executable file

Binary file not shown.

1682
Exercise8/Data/movie_ids.txt Executable file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

1028
Exercise8/exercise8.ipynb Executable file

File diff suppressed because it is too large Load Diff

269
Exercise8/utils.py Executable file
View File

@@ -0,0 +1,269 @@
import numpy as np
import sys
from os.path import join
from matplotlib import pyplot
sys.path.append('..')
from submission import SubmissionBase
def normalizeRatings(Y, R):
"""
Preprocess data by subtracting mean rating for every movie (every row).
Parameters
----------
Y : array_like
The user ratings for all movies. A matrix of shape (num_movies x num_users).
R : array_like
Indicator matrix for movies rated by users. A matrix of shape (num_movies x num_users).
Returns
-------
Ynorm : array_like
A matrix of same shape as Y, after mean normalization.
Ymean : array_like
A vector of shape (num_movies, ) containing the mean rating for each movie.
"""
m, n = Y.shape
Ymean = np.zeros(m)
Ynorm = np.zeros(Y.shape)
for i in range(m):
idx = R[i, :] == 1
Ymean[i] = np.mean(Y[i, idx])
Ynorm[i, idx] = Y[i, idx] - Ymean[i]
return Ynorm, Ymean
def loadMovieList():
"""
Reads the fixed movie list in movie_ids.txt and returns a list of movie names.
Returns
-------
movieNames : list
A list of strings, representing all movie names.
"""
# Read the fixed movieulary list
with open(join('Data', 'movie_ids.txt'), encoding='ISO-8859-1') as fid:
movies = fid.readlines()
movieNames = []
for movie in movies:
parts = movie.split()
movieNames.append(' '.join(parts[1:]).strip())
return movieNames
def computeNumericalGradient(J, theta, e=1e-4):
"""
Computes the gradient using "finite differences" and gives us a numerical estimate of the
gradient.
Parameters
----------
J : func
The cost function which will be used to estimate its numerical gradient.
theta : array_like
The one dimensional unrolled network parameters. The numerical gradient is computed at
those given parameters.
e : float (optional)
The value to use for epsilon for computing the finite difference.
Returns
-------
numgrad : array_like
The numerical gradient with respect to theta. Has same shape as theta.
Notes
-----
The following code implements numerical gradient checking, and
returns the numerical gradient. It sets `numgrad[i]` to (a numerical
approximation of) the partial derivative of J with respect to the
i-th input argument, evaluated at theta. (i.e., `numgrad[i]` should
be the (approximately) the partial derivative of J with respect
to theta[i].)
"""
numgrad = np.zeros(theta.shape)
perturb = np.diag(e * np.ones(theta.shape))
for i in range(theta.size):
loss1, _ = J(theta - perturb[:, i])
loss2, _ = J(theta + perturb[:, i])
numgrad[i] = (loss2 - loss1)/(2*e)
return numgrad
def checkCostFunction(cofiCostFunc, lambda_=0.):
"""
Creates a collaborative filtering problem to check your cost function and gradients.
It will output the analytical gradients produced by your code and the numerical gradients
(computed using computeNumericalGradient). These two gradient computations should result
in very similar values.
Parameters
----------
cofiCostFunc: func
Implementation of the cost function.
lambda_ : float, optional
The regularization parameter.
"""
# Create small problem
X_t = np.random.rand(4, 3)
Theta_t = np.random.rand(5, 3)
# Zap out most entries
Y = np.dot(X_t, Theta_t.T)
Y[np.random.rand(*Y.shape) > 0.5] = 0
R = np.zeros(Y.shape)
R[Y != 0] = 1
# Run Gradient Checking
X = np.random.randn(*X_t.shape)
Theta = np.random.randn(*Theta_t.shape)
num_movies, num_users = Y.shape
num_features = Theta_t.shape[1]
params = np.concatenate([X.ravel(), Theta.ravel()])
numgrad = computeNumericalGradient(
lambda x: cofiCostFunc(x, Y, R, num_users, num_movies, num_features, lambda_), params)
cost, grad = cofiCostFunc(params, Y, R, num_users,num_movies, num_features, lambda_)
print(np.stack([numgrad, grad], axis=1))
print('\nThe above two columns you get should be very similar.'
'(Left-Your Numerical Gradient, Right-Analytical Gradient)')
diff = np.linalg.norm(numgrad-grad)/np.linalg.norm(numgrad+grad)
print('If your cost function implementation is correct, then '
'the relative difference will be small (less than 1e-9).')
print('\nRelative Difference: %g' % diff)
def multivariateGaussian(X, mu, Sigma2):
"""
Computes the probability density function of the multivariate gaussian distribution.
Parameters
----------
X : array_like
The dataset of shape (m x n). Where there are m examples of n-dimensions.
mu : array_like
A vector of shape (n,) contains the means for each dimension (feature).
Sigma2 : array_like
Either a vector of shape (n,) containing the variances of independent features
(i.e. it is the diagonal of the correlation matrix), or the full
correlation matrix of shape (n x n) which can represent dependent features.
Returns
------
p : array_like
A vector of shape (m,) which contains the computed probabilities at each of the
provided examples.
"""
k = mu.size
# if sigma is given as a diagonal, compute the matrix
if Sigma2.ndim == 1:
Sigma2 = np.diag(Sigma2)
X = X - mu
p = (2 * np.pi) ** (- k / 2) * np.linalg.det(Sigma2) ** (-0.5)\
* np.exp(-0.5 * np.sum(np.dot(X, np.linalg.pinv(Sigma2)) * X, axis=1))
return p
def visualizeFit(X, mu, sigma2):
"""
Visualize the dataset and its estimated distribution.
This visualization shows you the probability density function of the Gaussian distribution.
Each example has a location (x1, x2) that depends on its feature values.
Parameters
----------
X : array_like
The dataset of shape (m x 2). Where there are m examples of 2-dimensions. We need at most
2-D features to be able to visualize the distribution.
mu : array_like
A vector of shape (n,) contains the means for each dimension (feature).
sigma2 : array_like
Either a vector of shape (n,) containing the variances of independent features
(i.e. it is the diagonal of the correlation matrix), or the full
correlation matrix of shape (n x n) which can represent dependent features.
"""
X1, X2 = np.meshgrid(np.arange(0, 35.5, 0.5), np.arange(0, 35.5, 0.5))
Z = multivariateGaussian(np.stack([X1.ravel(), X2.ravel()], axis=1), mu, sigma2)
Z = Z.reshape(X1.shape)
pyplot.plot(X[:, 0], X[:, 1], 'bx', mec='b', mew=2, ms=8)
if np.all(abs(Z) != np.inf):
pyplot.contour(X1, X2, Z, levels=10**(np.arange(-20., 1, 3)), zorder=100)
class Grader(SubmissionBase):
# Random Test Cases
n_u = 3
n_m = 4
n = 5
X = np.sin(np.arange(1, 1 + n_m * n)).reshape(n_m, n, order='F')
Theta = np.cos(np.arange(1, 1 + n_u * n)).reshape(n_u, n, order='F')
Y = np.sin(np.arange(1, 1 + 2 * n_m * n_u, 2)).reshape(n_m, n_u, order='F')
R = Y > 0.5
pval = np.concatenate([abs(Y.ravel('F')), [0.001], [1]])
Y = Y * R # set 'Y' values to 0 for movies not reviewed
yval = np.concatenate([R.ravel('F'), [1], [0]])
#
params = np.concatenate([X.ravel(), Theta.ravel()])
def __init__(self):
part_names = ['Estimate Gaussian Parameters',
'Select Threshold',
'Collaborative Filtering Cost',
'Collaborative Filtering Gradient',
'Regularized Cost',
'Regularized Gradient']
super().__init__('anomaly-detection-and-recommender-systems', part_names)
def __iter__(self):
for part_id in range(1, 7):
try:
func = self.functions[part_id]
# Each part has different expected arguments/different function
if part_id == 1:
res = np.hstack(func(self.X)).tolist()
elif part_id == 2:
res = np.hstack(func(self.yval, self.pval)).tolist()
elif part_id == 3:
J, grad = func(self.params, self.Y, self.R, self.n_u, self.n_m, self.n)
res = J
elif part_id == 4:
J, grad = func(self.params, self.Y, self.R, self.n_u, self.n_m, self.n, 0)
xgrad = grad[:self.n_m*self.n].reshape(self.n_m, self.n)
thetagrad = grad[self.n_m*self.n:].reshape(self.n_u, self.n)
res = np.hstack([xgrad.ravel('F'), thetagrad.ravel('F')]).tolist()
elif part_id == 5:
res, _ = func(self.params, self.Y, self.R, self.n_u, self.n_m, self.n, 1.5)
elif part_id == 6:
J, grad = func(self.params, self.Y, self.R, self.n_u, self.n_m, self.n, 1.5)
xgrad = grad[:self.n_m*self.n].reshape(self.n_m, self.n)
thetagrad = grad[self.n_m*self.n:].reshape(self.n_u, self.n)
res = np.hstack([xgrad.ravel('F'), thetagrad.ravel('F')]).tolist()
else:
raise KeyError
yield part_id, res
except KeyError:
yield part_id, 0