Add exercise 8
This commit is contained in:
		
							parent
							
								
									beb652a5be
								
							
						
					
					
						commit
						33e8cbac01
					
				
					 20 changed files with 3130 additions and 0 deletions
				
			
		
							
								
								
									
										
											BIN
										
									
								
								ex8.pdf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ex8.pdf
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										48
									
								
								ex8/checkCostFunction.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								ex8/checkCostFunction.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,48 @@
 | 
				
			||||||
 | 
					function checkCostFunction(lambda)
 | 
				
			||||||
 | 
					%CHECKCOSTFUNCTION Creates a collaborative filering problem 
 | 
				
			||||||
 | 
					%to check your cost function and gradients
 | 
				
			||||||
 | 
					%   CHECKCOSTFUNCTION(lambda) Creates a collaborative filering 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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% Set lambda
 | 
				
			||||||
 | 
					if ~exist('lambda', 'var') || isempty(lambda)
 | 
				
			||||||
 | 
					    lambda = 0;
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% Create small problem
 | 
				
			||||||
 | 
					X_t = rand(4, 3);
 | 
				
			||||||
 | 
					Theta_t = rand(5, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% Zap out most entries
 | 
				
			||||||
 | 
					Y = X_t * Theta_t';
 | 
				
			||||||
 | 
					Y(rand(size(Y)) > 0.5) = 0;
 | 
				
			||||||
 | 
					R = zeros(size(Y));
 | 
				
			||||||
 | 
					R(Y ~= 0) = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% Run Gradient Checking
 | 
				
			||||||
 | 
					X = randn(size(X_t));
 | 
				
			||||||
 | 
					Theta = randn(size(Theta_t));
 | 
				
			||||||
 | 
					num_users = size(Y, 2);
 | 
				
			||||||
 | 
					num_movies = size(Y, 1);
 | 
				
			||||||
 | 
					num_features = size(Theta_t, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					numgrad = computeNumericalGradient( ...
 | 
				
			||||||
 | 
					                @(t) cofiCostFunc(t, Y, R, num_users, num_movies, ...
 | 
				
			||||||
 | 
					                                num_features, lambda), [X(:); Theta(:)]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[cost, grad] = cofiCostFunc([X(:); Theta(:)],  Y, R, num_users, ...
 | 
				
			||||||
 | 
					                          num_movies, num_features, lambda);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					disp([numgrad grad]);
 | 
				
			||||||
 | 
					fprintf(['The above two columns you get should be very similar.\n' ...
 | 
				
			||||||
 | 
					         '(Left-Your Numerical Gradient, Right-Analytical Gradient)\n\n']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					diff = norm(numgrad-grad)/norm(numgrad+grad);
 | 
				
			||||||
 | 
					fprintf(['If your backpropagation implementation is correct, then \n' ...
 | 
				
			||||||
 | 
					         'the relative difference will be small (less than 1e-9). \n' ...
 | 
				
			||||||
 | 
					         '\nRelative Difference: %g\n'], diff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										62
									
								
								ex8/cofiCostFunc.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								ex8/cofiCostFunc.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,62 @@
 | 
				
			||||||
 | 
					function [J, grad] = cofiCostFunc(params, Y, R, num_users, num_movies, ...
 | 
				
			||||||
 | 
					                                  num_features, lambda)
 | 
				
			||||||
 | 
					%COFICOSTFUNC Collaborative filtering cost function
 | 
				
			||||||
 | 
					%   [J, grad] = COFICOSTFUNC(params, Y, R, num_users, num_movies, ...
 | 
				
			||||||
 | 
					%   num_features, lambda) returns the cost and gradient for the
 | 
				
			||||||
 | 
					%   collaborative filtering problem.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% Unfold the U and W matrices from params
 | 
				
			||||||
 | 
					X = reshape(params(1:num_movies*num_features), num_movies, num_features);
 | 
				
			||||||
 | 
					Theta = reshape(params(num_movies*num_features+1:end), ...
 | 
				
			||||||
 | 
					                num_users, num_features);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					% You need to return the following values correctly
 | 
				
			||||||
 | 
					J = 0;
 | 
				
			||||||
 | 
					X_grad = zeros(size(X));
 | 
				
			||||||
 | 
					Theta_grad = zeros(size(Theta));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% ====================== YOUR CODE HERE ======================
 | 
				
			||||||
 | 
					% Instructions: Compute the cost function and gradient for collaborative
 | 
				
			||||||
 | 
					%               filtering. Concretely, you should first implement the cost
 | 
				
			||||||
 | 
					%               function (without regularization) and make sure it is
 | 
				
			||||||
 | 
					%               matches our costs. After that, you should implement the 
 | 
				
			||||||
 | 
					%               gradient and use the checkCostFunction routine to check
 | 
				
			||||||
 | 
					%               that the gradient is correct. Finally, you should implement
 | 
				
			||||||
 | 
					%               regularization.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					% Notes: X - num_movies  x num_features matrix of movie features
 | 
				
			||||||
 | 
					%        Theta - num_users  x num_features matrix of user features
 | 
				
			||||||
 | 
					%        Y - num_movies x num_users matrix of user ratings of movies
 | 
				
			||||||
 | 
					%        R - num_movies x num_users matrix, where R(i, j) = 1 if the 
 | 
				
			||||||
 | 
					%            i-th movie was rated by the j-th user
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					% You should set the following variables correctly:
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%        X_grad - num_movies x num_features matrix, containing the 
 | 
				
			||||||
 | 
					%                 partial derivatives w.r.t. to each element of X
 | 
				
			||||||
 | 
					%        Theta_grad - num_users x num_features matrix, containing the 
 | 
				
			||||||
 | 
					%                     partial derivatives w.r.t. to each element of Theta
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% =============================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					grad = [X_grad(:); Theta_grad(:)];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										29
									
								
								ex8/computeNumericalGradient.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								ex8/computeNumericalGradient.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					function numgrad = computeNumericalGradient(J, theta)
 | 
				
			||||||
 | 
					%COMPUTENUMERICALGRADIENT Computes the gradient using "finite differences"
 | 
				
			||||||
 | 
					%and gives us a numerical estimate of the gradient.
 | 
				
			||||||
 | 
					%   numgrad = COMPUTENUMERICALGRADIENT(J, theta) computes the numerical
 | 
				
			||||||
 | 
					%   gradient of the function J around theta. Calling y = J(theta) should
 | 
				
			||||||
 | 
					%   return the function value at 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 = zeros(size(theta));
 | 
				
			||||||
 | 
					perturb = zeros(size(theta));
 | 
				
			||||||
 | 
					e = 1e-4;
 | 
				
			||||||
 | 
					for p = 1:numel(theta)
 | 
				
			||||||
 | 
					    % Set perturbation vector
 | 
				
			||||||
 | 
					    perturb(p) = e;
 | 
				
			||||||
 | 
					    loss1 = J(theta - perturb);
 | 
				
			||||||
 | 
					    loss2 = J(theta + perturb);
 | 
				
			||||||
 | 
					    % Compute Numerical Gradient
 | 
				
			||||||
 | 
					    numgrad(p) = (loss2 - loss1) / (2*e);
 | 
				
			||||||
 | 
					    perturb(p) = 0;
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										36
									
								
								ex8/estimateGaussian.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								ex8/estimateGaussian.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					function [mu sigma2] = estimateGaussian(X)
 | 
				
			||||||
 | 
					%ESTIMATEGAUSSIAN This function estimates the parameters of a 
 | 
				
			||||||
 | 
					%Gaussian distribution using the data in X
 | 
				
			||||||
 | 
					%   [mu sigma2] = estimateGaussian(X), 
 | 
				
			||||||
 | 
					%   The input X is the dataset with each n-dimensional data point in one row
 | 
				
			||||||
 | 
					%   The output is an n-dimensional vector mu, the mean of the data set
 | 
				
			||||||
 | 
					%   and the variances sigma^2, an n x 1 vector
 | 
				
			||||||
 | 
					% 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% Useful variables
 | 
				
			||||||
 | 
					[m, n] = size(X);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% You should return these values correctly
 | 
				
			||||||
 | 
					mu = zeros(n, 1);
 | 
				
			||||||
 | 
					sigma2 = zeros(n, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% ====================== YOUR CODE HERE ======================
 | 
				
			||||||
 | 
					% Instructions: Compute the mean of the data and the variances
 | 
				
			||||||
 | 
					%               In particular, mu(i) should contain the mean of
 | 
				
			||||||
 | 
					%               the data for the i-th feature and sigma2(i)
 | 
				
			||||||
 | 
					%               should contain variance of the i-th feature.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% =============================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										123
									
								
								ex8/ex8.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								ex8/ex8.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,123 @@
 | 
				
			||||||
 | 
					%% Machine Learning Online Class
 | 
				
			||||||
 | 
					%  Exercise 8 | Anomaly Detection and Collaborative Filtering
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%  Instructions
 | 
				
			||||||
 | 
					%  ------------
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%  This file contains code that helps you get started on the
 | 
				
			||||||
 | 
					%  exercise. You will need to complete the following functions:
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%     estimateGaussian.m
 | 
				
			||||||
 | 
					%     selectThreshold.m
 | 
				
			||||||
 | 
					%     cofiCostFunc.m
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%  For this exercise, you will not need to change any code in this file,
 | 
				
			||||||
 | 
					%  or any other files other than those mentioned above.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% Initialization
 | 
				
			||||||
 | 
					clear ; close all; clc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% ================== Part 1: Load Example Dataset  ===================
 | 
				
			||||||
 | 
					%  We start this exercise by using a small dataset that is easy to
 | 
				
			||||||
 | 
					%  visualize.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%  Our example case consists of 2 network server statistics across
 | 
				
			||||||
 | 
					%  several machines: the latency and throughput of each machine.
 | 
				
			||||||
 | 
					%  This exercise will help us find possibly faulty (or very fast) machines.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('Visualizing example dataset for outlier detection.\n\n');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  The following command loads the dataset. You should now have the
 | 
				
			||||||
 | 
					%  variables X, Xval, yval in your environment
 | 
				
			||||||
 | 
					load('ex8data1.mat');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Visualize the example dataset
 | 
				
			||||||
 | 
					plot(X(:, 1), X(:, 2), 'bx');
 | 
				
			||||||
 | 
					axis([0 30 0 30]);
 | 
				
			||||||
 | 
					xlabel('Latency (ms)');
 | 
				
			||||||
 | 
					ylabel('Throughput (mb/s)');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('Program paused. Press enter to continue.\n');
 | 
				
			||||||
 | 
					pause
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% ================== Part 2: Estimate the dataset statistics ===================
 | 
				
			||||||
 | 
					%  For this exercise, we assume a Gaussian distribution for the dataset.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%  We first estimate the parameters of our assumed Gaussian distribution, 
 | 
				
			||||||
 | 
					%  then compute the probabilities for each of the points and then visualize 
 | 
				
			||||||
 | 
					%  both the overall distribution and where each of the points falls in 
 | 
				
			||||||
 | 
					%  terms of that distribution.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					fprintf('Visualizing Gaussian fit.\n\n');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Estimate my and sigma2
 | 
				
			||||||
 | 
					[mu sigma2] = estimateGaussian(X);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Returns the density of the multivariate normal at each data point (row) 
 | 
				
			||||||
 | 
					%  of X
 | 
				
			||||||
 | 
					p = multivariateGaussian(X, mu, sigma2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Visualize the fit
 | 
				
			||||||
 | 
					visualizeFit(X,  mu, sigma2);
 | 
				
			||||||
 | 
					xlabel('Latency (ms)');
 | 
				
			||||||
 | 
					ylabel('Throughput (mb/s)');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('Program paused. Press enter to continue.\n');
 | 
				
			||||||
 | 
					pause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% ================== Part 3: Find Outliers ===================
 | 
				
			||||||
 | 
					%  Now you will find a good epsilon threshold using a cross-validation set
 | 
				
			||||||
 | 
					%  probabilities given the estimated Gaussian distribution
 | 
				
			||||||
 | 
					% 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pval = multivariateGaussian(Xval, mu, sigma2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[epsilon F1] = selectThreshold(yval, pval);
 | 
				
			||||||
 | 
					fprintf('Best epsilon found using cross-validation: %e\n', epsilon);
 | 
				
			||||||
 | 
					fprintf('Best F1 on Cross Validation Set:  %f\n', F1);
 | 
				
			||||||
 | 
					fprintf('   (you should see a value epsilon of about 8.99e-05)\n\n');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Find the outliers in the training set and plot the
 | 
				
			||||||
 | 
					outliers = find(p < epsilon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Draw a red circle around those outliers
 | 
				
			||||||
 | 
					hold on
 | 
				
			||||||
 | 
					plot(X(outliers, 1), X(outliers, 2), 'ro', 'LineWidth', 2, 'MarkerSize', 10);
 | 
				
			||||||
 | 
					hold off
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('Program paused. Press enter to continue.\n');
 | 
				
			||||||
 | 
					pause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% ================== Part 4: Multidimensional Outliers ===================
 | 
				
			||||||
 | 
					%  We will now use the code from the previous part and apply it to a 
 | 
				
			||||||
 | 
					%  harder problem in which more features describe each datapoint and only 
 | 
				
			||||||
 | 
					%  some features indicate whether a point is an outlier.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Loads the second dataset. You should now have the
 | 
				
			||||||
 | 
					%  variables X, Xval, yval in your environment
 | 
				
			||||||
 | 
					load('ex8data2.mat');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Apply the same steps to the larger dataset
 | 
				
			||||||
 | 
					[mu sigma2] = estimateGaussian(X);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Training set 
 | 
				
			||||||
 | 
					p = multivariateGaussian(X, mu, sigma2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Cross-validation set
 | 
				
			||||||
 | 
					pval = multivariateGaussian(Xval, mu, sigma2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Find the best threshold
 | 
				
			||||||
 | 
					[epsilon F1] = selectThreshold(yval, pval);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('Best epsilon found using cross-validation: %e\n', epsilon);
 | 
				
			||||||
 | 
					fprintf('Best F1 on Cross Validation Set:  %f\n', F1);
 | 
				
			||||||
 | 
					fprintf('# Outliers found: %d\n', sum(p < epsilon));
 | 
				
			||||||
 | 
					fprintf('   (you should see a value epsilon of about 1.38e-18)\n\n');
 | 
				
			||||||
 | 
					pause
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										237
									
								
								ex8/ex8_cofi.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								ex8/ex8_cofi.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,237 @@
 | 
				
			||||||
 | 
					%% Machine Learning Online Class
 | 
				
			||||||
 | 
					%  Exercise 8 | Anomaly Detection and Collaborative Filtering
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%  Instructions
 | 
				
			||||||
 | 
					%  ------------
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%  This file contains code that helps you get started on the
 | 
				
			||||||
 | 
					%  exercise. You will need to complete the following functions:
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%     estimateGaussian.m
 | 
				
			||||||
 | 
					%     selectThreshold.m
 | 
				
			||||||
 | 
					%     cofiCostFunc.m
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%  For this exercise, you will not need to change any code in this file,
 | 
				
			||||||
 | 
					%  or any other files other than those mentioned above.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% =============== Part 1: Loading movie ratings dataset ================
 | 
				
			||||||
 | 
					%  You will start by loading the movie ratings dataset to understand the
 | 
				
			||||||
 | 
					%  structure of the data.
 | 
				
			||||||
 | 
					%  
 | 
				
			||||||
 | 
					fprintf('Loading movie ratings dataset.\n\n');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Load data
 | 
				
			||||||
 | 
					load ('ex8_movies.mat');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Y is a 1682x943 matrix, containing ratings (1-5) of 1682 movies on 
 | 
				
			||||||
 | 
					%  943 users
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%  R is a 1682x943 matrix, where R(i,j) = 1 if and only if user j gave a
 | 
				
			||||||
 | 
					%  rating to movie i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  From the matrix, we can compute statistics like average rating.
 | 
				
			||||||
 | 
					fprintf('Average rating for movie 1 (Toy Story): %f / 5\n\n', ...
 | 
				
			||||||
 | 
					        mean(Y(1, R(1, :))));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  We can "visualize" the ratings matrix by plotting it with imagesc
 | 
				
			||||||
 | 
					imagesc(Y);
 | 
				
			||||||
 | 
					ylabel('Movies');
 | 
				
			||||||
 | 
					xlabel('Users');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('\nProgram paused. Press enter to continue.\n');
 | 
				
			||||||
 | 
					pause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% ============ Part 2: Collaborative Filtering Cost Function ===========
 | 
				
			||||||
 | 
					%  You will now implement the cost function for collaborative filtering.
 | 
				
			||||||
 | 
					%  To help you debug your cost function, we have included set of weights
 | 
				
			||||||
 | 
					%  that we trained on that. Specifically, you should complete the code in 
 | 
				
			||||||
 | 
					%  cofiCostFunc.m to return J.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Load pre-trained weights (X, Theta, num_users, num_movies, num_features)
 | 
				
			||||||
 | 
					load ('ex8_movieParams.mat');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Reduce the data set size so that this runs faster
 | 
				
			||||||
 | 
					num_users = 4; num_movies = 5; num_features = 3;
 | 
				
			||||||
 | 
					X = X(1:num_movies, 1:num_features);
 | 
				
			||||||
 | 
					Theta = Theta(1:num_users, 1:num_features);
 | 
				
			||||||
 | 
					Y = Y(1:num_movies, 1:num_users);
 | 
				
			||||||
 | 
					R = R(1:num_movies, 1:num_users);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Evaluate cost function
 | 
				
			||||||
 | 
					J = cofiCostFunc([X(:) ; Theta(:)], Y, R, num_users, num_movies, ...
 | 
				
			||||||
 | 
					               num_features, 0);
 | 
				
			||||||
 | 
					           
 | 
				
			||||||
 | 
					fprintf(['Cost at loaded parameters: %f '...
 | 
				
			||||||
 | 
					         '\n(this value should be about 22.22)\n'], J);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('\nProgram paused. Press enter to continue.\n');
 | 
				
			||||||
 | 
					pause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% ============== Part 3: Collaborative Filtering Gradient ==============
 | 
				
			||||||
 | 
					%  Once your cost function matches up with ours, you should now implement 
 | 
				
			||||||
 | 
					%  the collaborative filtering gradient function. Specifically, you should 
 | 
				
			||||||
 | 
					%  complete the code in cofiCostFunc.m to return the grad argument.
 | 
				
			||||||
 | 
					%  
 | 
				
			||||||
 | 
					fprintf('\nChecking Gradients (without regularization) ... \n');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Check gradients by running checkNNGradients
 | 
				
			||||||
 | 
					checkCostFunction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('\nProgram paused. Press enter to continue.\n');
 | 
				
			||||||
 | 
					pause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% ========= Part 4: Collaborative Filtering Cost Regularization ========
 | 
				
			||||||
 | 
					%  Now, you should implement regularization for the cost function for 
 | 
				
			||||||
 | 
					%  collaborative filtering. You can implement it by adding the cost of
 | 
				
			||||||
 | 
					%  regularization to the original cost computation.
 | 
				
			||||||
 | 
					%  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Evaluate cost function
 | 
				
			||||||
 | 
					J = cofiCostFunc([X(:) ; Theta(:)], Y, R, num_users, num_movies, ...
 | 
				
			||||||
 | 
					               num_features, 1.5);
 | 
				
			||||||
 | 
					           
 | 
				
			||||||
 | 
					fprintf(['Cost at loaded parameters (lambda = 1.5): %f '...
 | 
				
			||||||
 | 
					         '\n(this value should be about 31.34)\n'], J);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('\nProgram paused. Press enter to continue.\n');
 | 
				
			||||||
 | 
					pause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% ======= Part 5: Collaborative Filtering Gradient Regularization ======
 | 
				
			||||||
 | 
					%  Once your cost matches up with ours, you should proceed to implement 
 | 
				
			||||||
 | 
					%  regularization for the gradient. 
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  
 | 
				
			||||||
 | 
					fprintf('\nChecking Gradients (with regularization) ... \n');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Check gradients by running checkNNGradients
 | 
				
			||||||
 | 
					checkCostFunction(1.5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('\nProgram paused. Press enter to continue.\n');
 | 
				
			||||||
 | 
					pause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% ============== Part 6: Entering ratings for a new user ===============
 | 
				
			||||||
 | 
					%  Before we will train the collaborative filtering model, we will first
 | 
				
			||||||
 | 
					%  add ratings that correspond to a new user that we just observed. This
 | 
				
			||||||
 | 
					%  part of the code will also allow you to put in your own ratings for the
 | 
				
			||||||
 | 
					%  movies in our dataset!
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					movieList = loadMovieList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Initialize my ratings
 | 
				
			||||||
 | 
					my_ratings = zeros(1682, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% Check the file movie_idx.txt for id of each movie in our dataset
 | 
				
			||||||
 | 
					% For example, Toy Story (1995) has ID 1, so to rate it "4", you can set
 | 
				
			||||||
 | 
					my_ratings(1) = 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% Or suppose did not enjoy Silence of the Lambs (1991), you can set
 | 
				
			||||||
 | 
					my_ratings(98) = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% We have selected a few movies we liked / did not like and the ratings we
 | 
				
			||||||
 | 
					% gave are as follows:
 | 
				
			||||||
 | 
					my_ratings(7) = 3;
 | 
				
			||||||
 | 
					my_ratings(12)= 5;
 | 
				
			||||||
 | 
					my_ratings(54) = 4;
 | 
				
			||||||
 | 
					my_ratings(64)= 5;
 | 
				
			||||||
 | 
					my_ratings(66)= 3;
 | 
				
			||||||
 | 
					my_ratings(69) = 5;
 | 
				
			||||||
 | 
					my_ratings(183) = 4;
 | 
				
			||||||
 | 
					my_ratings(226) = 5;
 | 
				
			||||||
 | 
					my_ratings(355)= 5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('\n\nNew user ratings:\n');
 | 
				
			||||||
 | 
					for i = 1:length(my_ratings)
 | 
				
			||||||
 | 
					    if my_ratings(i) > 0 
 | 
				
			||||||
 | 
					        fprintf('Rated %d for %s\n', my_ratings(i), ...
 | 
				
			||||||
 | 
					                 movieList{i});
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('\nProgram paused. Press enter to continue.\n');
 | 
				
			||||||
 | 
					pause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% ================== Part 7: Learning Movie Ratings ====================
 | 
				
			||||||
 | 
					%  Now, you will train the collaborative filtering model on a movie rating 
 | 
				
			||||||
 | 
					%  dataset of 1682 movies and 943 users
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('\nTraining collaborative filtering...\n');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Load data
 | 
				
			||||||
 | 
					load('ex8_movies.mat');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Y is a 1682x943 matrix, containing ratings (1-5) of 1682 movies by 
 | 
				
			||||||
 | 
					%  943 users
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%  R is a 1682x943 matrix, where R(i,j) = 1 if and only if user j gave a
 | 
				
			||||||
 | 
					%  rating to movie i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Add our own ratings to the data matrix
 | 
				
			||||||
 | 
					Y = [my_ratings Y];
 | 
				
			||||||
 | 
					R = [(my_ratings ~= 0) R];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Normalize Ratings
 | 
				
			||||||
 | 
					[Ynorm, Ymean] = normalizeRatings(Y, R);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%  Useful Values
 | 
				
			||||||
 | 
					num_users = size(Y, 2);
 | 
				
			||||||
 | 
					num_movies = size(Y, 1);
 | 
				
			||||||
 | 
					num_features = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% Set Initial Parameters (Theta, X)
 | 
				
			||||||
 | 
					X = randn(num_movies, num_features);
 | 
				
			||||||
 | 
					Theta = randn(num_users, num_features);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					initial_parameters = [X(:); Theta(:)];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% Set options for fmincg
 | 
				
			||||||
 | 
					options = optimset('GradObj', 'on', 'MaxIter', 100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% Set Regularization
 | 
				
			||||||
 | 
					lambda = 10;
 | 
				
			||||||
 | 
					theta = fmincg (@(t)(cofiCostFunc(t, Y, R, num_users, num_movies, ...
 | 
				
			||||||
 | 
					                                num_features, lambda)), ...
 | 
				
			||||||
 | 
					                initial_parameters, options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% Unfold the returned theta back into U and W
 | 
				
			||||||
 | 
					X = reshape(theta(1:num_movies*num_features), num_movies, num_features);
 | 
				
			||||||
 | 
					Theta = reshape(theta(num_movies*num_features+1:end), ...
 | 
				
			||||||
 | 
					                num_users, num_features);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('Recommender system learning completed.\n');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('\nProgram paused. Press enter to continue.\n');
 | 
				
			||||||
 | 
					pause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% ================== Part 8: Recommendation for you ====================
 | 
				
			||||||
 | 
					%  After training the model, you can now make recommendations by computing
 | 
				
			||||||
 | 
					%  the predictions matrix.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					p = X * Theta';
 | 
				
			||||||
 | 
					my_predictions = p(:,1) + Ymean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					movieList = loadMovieList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[r, ix] = sort(my_predictions, 'descend');
 | 
				
			||||||
 | 
					fprintf('\nTop recommendations for you:\n');
 | 
				
			||||||
 | 
					for i=1:10
 | 
				
			||||||
 | 
					    j = ix(i);
 | 
				
			||||||
 | 
					    fprintf('Predicting rating %.1f for movie %s\n', my_predictions(j), ...
 | 
				
			||||||
 | 
					            movieList{j});
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fprintf('\n\nOriginal ratings provided:\n');
 | 
				
			||||||
 | 
					for i = 1:length(my_ratings)
 | 
				
			||||||
 | 
					    if my_ratings(i) > 0 
 | 
				
			||||||
 | 
					        fprintf('Rated %d for %s\n', my_ratings(i), ...
 | 
				
			||||||
 | 
					                 movieList{i});
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								ex8/ex8_movieParams.mat
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ex8/ex8_movieParams.mat
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								ex8/ex8_movies.mat
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ex8/ex8_movies.mat
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								ex8/ex8data1.mat
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ex8/ex8data1.mat
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								ex8/ex8data2.mat
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ex8/ex8data2.mat
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										175
									
								
								ex8/fmincg.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								ex8/fmincg.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,175 @@
 | 
				
			||||||
 | 
					function [X, fX, i] = fmincg(f, X, options, P1, P2, P3, P4, P5)
 | 
				
			||||||
 | 
					% Minimize a continuous differentialble multivariate function. Starting point
 | 
				
			||||||
 | 
					% is given by "X" (D by 1), and the function named in the string "f", must
 | 
				
			||||||
 | 
					% return a function value and a vector of partial derivatives. The Polack-
 | 
				
			||||||
 | 
					% Ribiere flavour of conjugate gradients is used to compute search directions,
 | 
				
			||||||
 | 
					% and a line search using quadratic and cubic polynomial approximations and the
 | 
				
			||||||
 | 
					% Wolfe-Powell stopping criteria is used together with the slope ratio method
 | 
				
			||||||
 | 
					% for guessing initial step sizes. Additionally a bunch of checks are made to
 | 
				
			||||||
 | 
					% make sure that exploration is taking place and that extrapolation will not
 | 
				
			||||||
 | 
					% be unboundedly large. The "length" gives the length of the run: if it is
 | 
				
			||||||
 | 
					% positive, it gives the maximum number of line searches, if negative its
 | 
				
			||||||
 | 
					% absolute gives the maximum allowed number of function evaluations. You can
 | 
				
			||||||
 | 
					% (optionally) give "length" a second component, which will indicate the
 | 
				
			||||||
 | 
					% reduction in function value to be expected in the first line-search (defaults
 | 
				
			||||||
 | 
					% to 1.0). The function returns when either its length is up, or if no further
 | 
				
			||||||
 | 
					% progress can be made (ie, we are at a minimum, or so close that due to
 | 
				
			||||||
 | 
					% numerical problems, we cannot get any closer). If the function terminates
 | 
				
			||||||
 | 
					% within a few iterations, it could be an indication that the function value
 | 
				
			||||||
 | 
					% and derivatives are not consistent (ie, there may be a bug in the
 | 
				
			||||||
 | 
					% implementation of your "f" function). The function returns the found
 | 
				
			||||||
 | 
					% solution "X", a vector of function values "fX" indicating the progress made
 | 
				
			||||||
 | 
					% and "i" the number of iterations (line searches or function evaluations,
 | 
				
			||||||
 | 
					% depending on the sign of "length") used.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					% Usage: [X, fX, i] = fmincg(f, X, options, P1, P2, P3, P4, P5)
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					% See also: checkgrad 
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					% Copyright (C) 2001 and 2002 by Carl Edward Rasmussen. Date 2002-02-13
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					% (C) Copyright 1999, 2000 & 2001, Carl Edward Rasmussen
 | 
				
			||||||
 | 
					% 
 | 
				
			||||||
 | 
					% Permission is granted for anyone to copy, use, or modify these
 | 
				
			||||||
 | 
					% programs and accompanying documents for purposes of research or
 | 
				
			||||||
 | 
					% education, provided this copyright notice is retained, and note is
 | 
				
			||||||
 | 
					% made of any changes that have been made.
 | 
				
			||||||
 | 
					% 
 | 
				
			||||||
 | 
					% These programs and documents are distributed without any warranty,
 | 
				
			||||||
 | 
					% express or implied.  As the programs were written for research
 | 
				
			||||||
 | 
					% purposes only, they have not been tested to the degree that would be
 | 
				
			||||||
 | 
					% advisable in any important application.  All use of these programs is
 | 
				
			||||||
 | 
					% entirely at the user's own risk.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					% [ml-class] Changes Made:
 | 
				
			||||||
 | 
					% 1) Function name and argument specifications
 | 
				
			||||||
 | 
					% 2) Output display
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% Read options
 | 
				
			||||||
 | 
					if exist('options', 'var') && ~isempty(options) && isfield(options, 'MaxIter')
 | 
				
			||||||
 | 
					    length = options.MaxIter;
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					    length = 100;
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RHO = 0.01;                            % a bunch of constants for line searches
 | 
				
			||||||
 | 
					SIG = 0.5;       % RHO and SIG are the constants in the Wolfe-Powell conditions
 | 
				
			||||||
 | 
					INT = 0.1;    % don't reevaluate within 0.1 of the limit of the current bracket
 | 
				
			||||||
 | 
					EXT = 3.0;                    % extrapolate maximum 3 times the current bracket
 | 
				
			||||||
 | 
					MAX = 20;                         % max 20 function evaluations per line search
 | 
				
			||||||
 | 
					RATIO = 100;                                      % maximum allowed slope ratio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					argstr = ['feval(f, X'];                      % compose string used to call function
 | 
				
			||||||
 | 
					for i = 1:(nargin - 3)
 | 
				
			||||||
 | 
					  argstr = [argstr, ',P', int2str(i)];
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					argstr = [argstr, ')'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if max(size(length)) == 2, red=length(2); length=length(1); else red=1; end
 | 
				
			||||||
 | 
					S=['Iteration '];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					i = 0;                                            % zero the run length counter
 | 
				
			||||||
 | 
					ls_failed = 0;                             % no previous line search has failed
 | 
				
			||||||
 | 
					fX = [];
 | 
				
			||||||
 | 
					[f1 df1] = eval(argstr);                      % get function value and gradient
 | 
				
			||||||
 | 
					i = i + (length<0);                                            % count epochs?!
 | 
				
			||||||
 | 
					s = -df1;                                        % search direction is steepest
 | 
				
			||||||
 | 
					d1 = -s'*s;                                                 % this is the slope
 | 
				
			||||||
 | 
					z1 = red/(1-d1);                                  % initial step is red/(|s|+1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					while i < abs(length)                                      % while not finished
 | 
				
			||||||
 | 
					  i = i + (length>0);                                      % count iterations?!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  X0 = X; f0 = f1; df0 = df1;                   % make a copy of current values
 | 
				
			||||||
 | 
					  X = X + z1*s;                                             % begin line search
 | 
				
			||||||
 | 
					  [f2 df2] = eval(argstr);
 | 
				
			||||||
 | 
					  i = i + (length<0);                                          % count epochs?!
 | 
				
			||||||
 | 
					  d2 = df2'*s;
 | 
				
			||||||
 | 
					  f3 = f1; d3 = d1; z3 = -z1;             % initialize point 3 equal to point 1
 | 
				
			||||||
 | 
					  if length>0, M = MAX; else M = min(MAX, -length-i); end
 | 
				
			||||||
 | 
					  success = 0; limit = -1;                     % initialize quanteties
 | 
				
			||||||
 | 
					  while 1
 | 
				
			||||||
 | 
					    while ((f2 > f1+z1*RHO*d1) | (d2 > -SIG*d1)) & (M > 0) 
 | 
				
			||||||
 | 
					      limit = z1;                                         % tighten the bracket
 | 
				
			||||||
 | 
					      if f2 > f1
 | 
				
			||||||
 | 
					        z2 = z3 - (0.5*d3*z3*z3)/(d3*z3+f2-f3);                 % quadratic fit
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        A = 6*(f2-f3)/z3+3*(d2+d3);                                 % cubic fit
 | 
				
			||||||
 | 
					        B = 3*(f3-f2)-z3*(d3+2*d2);
 | 
				
			||||||
 | 
					        z2 = (sqrt(B*B-A*d2*z3*z3)-B)/A;       % numerical error possible - ok!
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					      if isnan(z2) | isinf(z2)
 | 
				
			||||||
 | 
					        z2 = z3/2;                  % if we had a numerical problem then bisect
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					      z2 = max(min(z2, INT*z3),(1-INT)*z3);  % don't accept too close to limits
 | 
				
			||||||
 | 
					      z1 = z1 + z2;                                           % update the step
 | 
				
			||||||
 | 
					      X = X + z2*s;
 | 
				
			||||||
 | 
					      [f2 df2] = eval(argstr);
 | 
				
			||||||
 | 
					      M = M - 1; i = i + (length<0);                           % count epochs?!
 | 
				
			||||||
 | 
					      d2 = df2'*s;
 | 
				
			||||||
 | 
					      z3 = z3-z2;                    % z3 is now relative to the location of z2
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    if f2 > f1+z1*RHO*d1 | d2 > -SIG*d1
 | 
				
			||||||
 | 
					      break;                                                % this is a failure
 | 
				
			||||||
 | 
					    elseif d2 > SIG*d1
 | 
				
			||||||
 | 
					      success = 1; break;                                             % success
 | 
				
			||||||
 | 
					    elseif M == 0
 | 
				
			||||||
 | 
					      break;                                                          % failure
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    A = 6*(f2-f3)/z3+3*(d2+d3);                      % make cubic extrapolation
 | 
				
			||||||
 | 
					    B = 3*(f3-f2)-z3*(d3+2*d2);
 | 
				
			||||||
 | 
					    z2 = -d2*z3*z3/(B+sqrt(B*B-A*d2*z3*z3));        % num. error possible - ok!
 | 
				
			||||||
 | 
					    if ~isreal(z2) | isnan(z2) | isinf(z2) | z2 < 0   % num prob or wrong sign?
 | 
				
			||||||
 | 
					      if limit < -0.5                               % if we have no upper limit
 | 
				
			||||||
 | 
					        z2 = z1 * (EXT-1);                 % the extrapolate the maximum amount
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        z2 = (limit-z1)/2;                                   % otherwise bisect
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    elseif (limit > -0.5) & (z2+z1 > limit)          % extraplation beyond max?
 | 
				
			||||||
 | 
					      z2 = (limit-z1)/2;                                               % bisect
 | 
				
			||||||
 | 
					    elseif (limit < -0.5) & (z2+z1 > z1*EXT)       % extrapolation beyond limit
 | 
				
			||||||
 | 
					      z2 = z1*(EXT-1.0);                           % set to extrapolation limit
 | 
				
			||||||
 | 
					    elseif z2 < -z3*INT
 | 
				
			||||||
 | 
					      z2 = -z3*INT;
 | 
				
			||||||
 | 
					    elseif (limit > -0.5) & (z2 < (limit-z1)*(1.0-INT))   % too close to limit?
 | 
				
			||||||
 | 
					      z2 = (limit-z1)*(1.0-INT);
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    f3 = f2; d3 = d2; z3 = -z2;                  % set point 3 equal to point 2
 | 
				
			||||||
 | 
					    z1 = z1 + z2; X = X + z2*s;                      % update current estimates
 | 
				
			||||||
 | 
					    [f2 df2] = eval(argstr);
 | 
				
			||||||
 | 
					    M = M - 1; i = i + (length<0);                             % count epochs?!
 | 
				
			||||||
 | 
					    d2 = df2'*s;
 | 
				
			||||||
 | 
					  end                                                      % end of line search
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if success                                         % if line search succeeded
 | 
				
			||||||
 | 
					    f1 = f2; fX = [fX' f1]';
 | 
				
			||||||
 | 
					    fprintf('%s %4i | Cost: %4.6e\r', S, i, f1);
 | 
				
			||||||
 | 
					    s = (df2'*df2-df1'*df2)/(df1'*df1)*s - df2;      % Polack-Ribiere direction
 | 
				
			||||||
 | 
					    tmp = df1; df1 = df2; df2 = tmp;                         % swap derivatives
 | 
				
			||||||
 | 
					    d2 = df1'*s;
 | 
				
			||||||
 | 
					    if d2 > 0                                      % new slope must be negative
 | 
				
			||||||
 | 
					      s = -df1;                              % otherwise use steepest direction
 | 
				
			||||||
 | 
					      d2 = -s'*s;    
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    z1 = z1 * min(RATIO, d1/(d2-realmin));          % slope ratio but max RATIO
 | 
				
			||||||
 | 
					    d1 = d2;
 | 
				
			||||||
 | 
					    ls_failed = 0;                              % this line search did not fail
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    X = X0; f1 = f0; df1 = df0;  % restore point from before failed line search
 | 
				
			||||||
 | 
					    if ls_failed | i > abs(length)          % line search failed twice in a row
 | 
				
			||||||
 | 
					      break;                             % or we ran out of time, so we give up
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    tmp = df1; df1 = df2; df2 = tmp;                         % swap derivatives
 | 
				
			||||||
 | 
					    s = -df1;                                                    % try steepest
 | 
				
			||||||
 | 
					    d1 = -s'*s;
 | 
				
			||||||
 | 
					    z1 = 1/(1-d1);                     
 | 
				
			||||||
 | 
					    ls_failed = 1;                                    % this line search failed
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  if exist('OCTAVE_VERSION')
 | 
				
			||||||
 | 
					    fflush(stdout);
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					fprintf('\n');
 | 
				
			||||||
							
								
								
									
										25
									
								
								ex8/loadMovieList.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								ex8/loadMovieList.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,25 @@
 | 
				
			||||||
 | 
					function movieList = loadMovieList()
 | 
				
			||||||
 | 
					%GETMOVIELIST reads the fixed movie list in movie.txt and returns a
 | 
				
			||||||
 | 
					%cell array of the words
 | 
				
			||||||
 | 
					%   movieList = GETMOVIELIST() reads the fixed movie list in movie.txt 
 | 
				
			||||||
 | 
					%   and returns a cell array of the words in movieList.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%% Read the fixed movieulary list
 | 
				
			||||||
 | 
					fid = fopen('movie_ids.txt');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% Store all movies in cell array movie{}
 | 
				
			||||||
 | 
					n = 1682;  % Total number of movies 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					movieList = cell(n, 1);
 | 
				
			||||||
 | 
					for i = 1:n
 | 
				
			||||||
 | 
					    % Read line
 | 
				
			||||||
 | 
					    line = fgets(fid);
 | 
				
			||||||
 | 
					    % Word Index (can ignore since it will be = i)
 | 
				
			||||||
 | 
					    [idx, movieName] = strtok(line, ' ');
 | 
				
			||||||
 | 
					    % Actual Word
 | 
				
			||||||
 | 
					    movieList{i} = strtrim(movieName);
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					fclose(fid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										1682
									
								
								ex8/movie_ids.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1682
									
								
								ex8/movie_ids.txt
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										22
									
								
								ex8/multivariateGaussian.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								ex8/multivariateGaussian.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,22 @@
 | 
				
			||||||
 | 
					function p = multivariateGaussian(X, mu, Sigma2)
 | 
				
			||||||
 | 
					%MULTIVARIATEGAUSSIAN Computes the probability density function of the
 | 
				
			||||||
 | 
					%multivariate gaussian distribution.
 | 
				
			||||||
 | 
					%    p = MULTIVARIATEGAUSSIAN(X, mu, Sigma2) Computes the probability 
 | 
				
			||||||
 | 
					%    density function of the examples X under the multivariate gaussian 
 | 
				
			||||||
 | 
					%    distribution with parameters mu and Sigma2. If Sigma2 is a matrix, it is
 | 
				
			||||||
 | 
					%    treated as the covariance matrix. If Sigma2 is a vector, it is treated
 | 
				
			||||||
 | 
					%    as the \sigma^2 values of the variances in each dimension (a diagonal
 | 
				
			||||||
 | 
					%    covariance matrix)
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					k = length(mu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (size(Sigma2, 2) == 1) || (size(Sigma2, 1) == 1)
 | 
				
			||||||
 | 
					    Sigma2 = diag(Sigma2);
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					X = bsxfun(@minus, X, mu(:)');
 | 
				
			||||||
 | 
					p = (2 * pi) ^ (- k / 2) * det(Sigma2) ^ (-0.5) * ...
 | 
				
			||||||
 | 
					    exp(-0.5 * sum(bsxfun(@times, X * pinv(Sigma2), X), 2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										17
									
								
								ex8/normalizeRatings.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								ex8/normalizeRatings.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,17 @@
 | 
				
			||||||
 | 
					function [Ynorm, Ymean] = normalizeRatings(Y, R)
 | 
				
			||||||
 | 
					%NORMALIZERATINGS Preprocess data by subtracting mean rating for every 
 | 
				
			||||||
 | 
					%movie (every row)
 | 
				
			||||||
 | 
					%   [Ynorm, Ymean] = NORMALIZERATINGS(Y, R) normalized Y so that each movie
 | 
				
			||||||
 | 
					%   has a rating of 0 on average, and returns the mean rating in Ymean.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[m, n] = size(Y);
 | 
				
			||||||
 | 
					Ymean = zeros(m, 1);
 | 
				
			||||||
 | 
					Ynorm = zeros(size(Y));
 | 
				
			||||||
 | 
					for i = 1:m
 | 
				
			||||||
 | 
					    idx = find(R(i, :) == 1);
 | 
				
			||||||
 | 
					    Ymean(i) = mean(Y(i, idx));
 | 
				
			||||||
 | 
					    Ynorm(i, idx) = Y(i, idx) - Ymean(i);
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										46
									
								
								ex8/selectThreshold.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								ex8/selectThreshold.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,46 @@
 | 
				
			||||||
 | 
					function [bestEpsilon bestF1] = selectThreshold(yval, pval)
 | 
				
			||||||
 | 
					%SELECTTHRESHOLD Find the best threshold (epsilon) to use for selecting
 | 
				
			||||||
 | 
					%outliers
 | 
				
			||||||
 | 
					%   [bestEpsilon bestF1] = SELECTTHRESHOLD(yval, pval) finds the best
 | 
				
			||||||
 | 
					%   threshold to use for selecting outliers based on the results from a
 | 
				
			||||||
 | 
					%   validation set (pval) and the ground truth (yval).
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bestEpsilon = 0;
 | 
				
			||||||
 | 
					bestF1 = 0;
 | 
				
			||||||
 | 
					F1 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					stepsize = (max(pval) - min(pval)) / 1000;
 | 
				
			||||||
 | 
					for epsilon = min(pval):stepsize:max(pval)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    % ====================== YOUR CODE HERE ======================
 | 
				
			||||||
 | 
					    % Instructions: Compute the F1 score of choosing epsilon as the
 | 
				
			||||||
 | 
					    %               threshold and place the value in F1. The code at the
 | 
				
			||||||
 | 
					    %               end of the loop will compare the F1 score for this
 | 
				
			||||||
 | 
					    %               choice of epsilon and set it to be the best epsilon if
 | 
				
			||||||
 | 
					    %               it is better than the current choice of epsilon.
 | 
				
			||||||
 | 
					    %               
 | 
				
			||||||
 | 
					    % Note: You can use predictions = (pval < epsilon) to get a binary vector
 | 
				
			||||||
 | 
					    %       of 0's and 1's of the outlier predictions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    % =============================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if F1 > bestF1
 | 
				
			||||||
 | 
					       bestF1 = F1;
 | 
				
			||||||
 | 
					       bestEpsilon = epsilon;
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										588
									
								
								ex8/submit.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										588
									
								
								ex8/submit.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,588 @@
 | 
				
			||||||
 | 
					function submit(partId, webSubmit)
 | 
				
			||||||
 | 
					%SUBMIT Submit your code and output to the ml-class servers
 | 
				
			||||||
 | 
					%   SUBMIT() will connect to the ml-class server and submit your solution
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fprintf('==\n== [ml-class] Submitting Solutions | Programming Exercise %s\n==\n', ...
 | 
				
			||||||
 | 
					          homework_id());
 | 
				
			||||||
 | 
					  if ~exist('partId', 'var') || isempty(partId)
 | 
				
			||||||
 | 
					    partId = promptPart();
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ~exist('webSubmit', 'var') || isempty(webSubmit)
 | 
				
			||||||
 | 
					    webSubmit = 0; % submit directly by default 
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  % Check valid partId
 | 
				
			||||||
 | 
					  partNames = validParts();
 | 
				
			||||||
 | 
					  if ~isValidPartId(partId)
 | 
				
			||||||
 | 
					    fprintf('!! Invalid homework part selected.\n');
 | 
				
			||||||
 | 
					    fprintf('!! Expected an integer from 1 to %d.\n', numel(partNames) + 1);
 | 
				
			||||||
 | 
					    fprintf('!! Submission Cancelled\n');
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ~exist('ml_login_data.mat','file')
 | 
				
			||||||
 | 
					    [login password] = loginPrompt();
 | 
				
			||||||
 | 
					    save('ml_login_data.mat','login','password');
 | 
				
			||||||
 | 
					  else  
 | 
				
			||||||
 | 
					    load('ml_login_data.mat');
 | 
				
			||||||
 | 
					    [login password] = quickLogin(login, password);
 | 
				
			||||||
 | 
					    save('ml_login_data.mat','login','password');
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if isempty(login)
 | 
				
			||||||
 | 
					    fprintf('!! Submission Cancelled\n');
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fprintf('\n== Connecting to ml-class ... '); 
 | 
				
			||||||
 | 
					  if exist('OCTAVE_VERSION') 
 | 
				
			||||||
 | 
					    fflush(stdout);
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  % Setup submit list
 | 
				
			||||||
 | 
					  if partId == numel(partNames) + 1
 | 
				
			||||||
 | 
					    submitParts = 1:numel(partNames);
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    submitParts = [partId];
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for s = 1:numel(submitParts)
 | 
				
			||||||
 | 
					    thisPartId = submitParts(s);
 | 
				
			||||||
 | 
					    if (~webSubmit) % submit directly to server
 | 
				
			||||||
 | 
					      [login, ch, signature, auxstring] = getChallenge(login, thisPartId);
 | 
				
			||||||
 | 
					      if isempty(login) || isempty(ch) || isempty(signature)
 | 
				
			||||||
 | 
					        % Some error occured, error string in first return element.
 | 
				
			||||||
 | 
					        fprintf('\n!! Error: %s\n\n', login);
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      % Attempt Submission with Challenge
 | 
				
			||||||
 | 
					      ch_resp = challengeResponse(login, password, ch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      [result, str] = submitSolution(login, ch_resp, thisPartId, ...
 | 
				
			||||||
 | 
					             output(thisPartId, auxstring), source(thisPartId), signature);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      partName = partNames{thisPartId};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      fprintf('\n== [ml-class] Submitted Assignment %s - Part %d - %s\n', ...
 | 
				
			||||||
 | 
					        homework_id(), thisPartId, partName);
 | 
				
			||||||
 | 
					      fprintf('== %s\n', strtrim(str));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if exist('OCTAVE_VERSION')
 | 
				
			||||||
 | 
					        fflush(stdout);
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      [result] = submitSolutionWeb(login, thisPartId, output(thisPartId), ...
 | 
				
			||||||
 | 
					                            source(thisPartId));
 | 
				
			||||||
 | 
					      result = base64encode(result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      fprintf('\nSave as submission file [submit_ex%s_part%d.txt (enter to accept default)]:', ...
 | 
				
			||||||
 | 
					        homework_id(), thisPartId);
 | 
				
			||||||
 | 
					      saveAsFile = input('', 's');
 | 
				
			||||||
 | 
					      if (isempty(saveAsFile))
 | 
				
			||||||
 | 
					        saveAsFile = sprintf('submit_ex%s_part%d.txt', homework_id(), thisPartId);
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      fid = fopen(saveAsFile, 'w');
 | 
				
			||||||
 | 
					      if (fid)
 | 
				
			||||||
 | 
					        fwrite(fid, result);
 | 
				
			||||||
 | 
					        fclose(fid);
 | 
				
			||||||
 | 
					        fprintf('\nSaved your solutions to %s.\n\n', saveAsFile);
 | 
				
			||||||
 | 
					        fprintf(['You can now submit your solutions through the web \n' ...
 | 
				
			||||||
 | 
					                 'form in the programming exercises. Select the corresponding \n' ...
 | 
				
			||||||
 | 
					                 'programming exercise to access the form.\n']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        fprintf('Unable to save to %s\n\n', saveAsFile);
 | 
				
			||||||
 | 
					        fprintf(['You can create a submission file by saving the \n' ...
 | 
				
			||||||
 | 
					                 'following text in a file: (press enter to continue)\n\n']);
 | 
				
			||||||
 | 
					        pause;
 | 
				
			||||||
 | 
					        fprintf(result);
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% ================== CONFIGURABLES FOR EACH HOMEWORK ==================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function id = homework_id() 
 | 
				
			||||||
 | 
					  id = '8';
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function [partNames] = validParts()
 | 
				
			||||||
 | 
					  partNames = { 'Estimate Gaussian Parameters', ...
 | 
				
			||||||
 | 
					                'Select Threshold' ...
 | 
				
			||||||
 | 
					                'Collaborative Filtering Cost', ...
 | 
				
			||||||
 | 
					                'Collaborative Filtering Gradient', ...
 | 
				
			||||||
 | 
					                'Regularized Cost', ...
 | 
				
			||||||
 | 
					                'Regularized Gradient' ...
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function srcs = sources()
 | 
				
			||||||
 | 
					  % Separated by part
 | 
				
			||||||
 | 
					  srcs = { { 'estimateGaussian.m' }, ...
 | 
				
			||||||
 | 
					           { 'selectThreshold.m' }, ...
 | 
				
			||||||
 | 
					           { 'cofiCostFunc.m' }, ...
 | 
				
			||||||
 | 
					           { 'cofiCostFunc.m' }, ...
 | 
				
			||||||
 | 
					           { 'cofiCostFunc.m' }, ...
 | 
				
			||||||
 | 
					           { 'cofiCostFunc.m' }, ...
 | 
				
			||||||
 | 
					           };
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function out = output(partId, auxstring)
 | 
				
			||||||
 | 
					  % Random Test Cases
 | 
				
			||||||
 | 
					  n_u = 3; n_m = 4; n = 5;
 | 
				
			||||||
 | 
					  X = reshape(sin(1:n_m*n), n_m, n);
 | 
				
			||||||
 | 
					  Theta = reshape(cos(1:n_u*n), n_u, n);
 | 
				
			||||||
 | 
					  Y = reshape(sin(1:2:2*n_m*n_u), n_m, n_u);
 | 
				
			||||||
 | 
					  R = Y > 0.5;
 | 
				
			||||||
 | 
					  pval = [abs(Y(:)) ; 0.001; 1];
 | 
				
			||||||
 | 
					  yval = [R(:) ; 1; 0];
 | 
				
			||||||
 | 
					  params = [X(:); Theta(:)];
 | 
				
			||||||
 | 
					  if partId == 1
 | 
				
			||||||
 | 
					    [mu sigma2] = estimateGaussian(X);
 | 
				
			||||||
 | 
					    out = sprintf('%0.5f ', [mu(:); sigma2(:)]);
 | 
				
			||||||
 | 
					  elseif partId == 2
 | 
				
			||||||
 | 
					    [bestEpsilon bestF1] = selectThreshold(yval, pval);
 | 
				
			||||||
 | 
					    out = sprintf('%0.5f ', [bestEpsilon(:); bestF1(:)]);
 | 
				
			||||||
 | 
					  elseif partId == 3
 | 
				
			||||||
 | 
					    [J] = cofiCostFunc(params, Y, R, n_u, n_m, ...
 | 
				
			||||||
 | 
					                       n, 0);
 | 
				
			||||||
 | 
					    out = sprintf('%0.5f ', J(:));
 | 
				
			||||||
 | 
					  elseif partId == 4
 | 
				
			||||||
 | 
					    [J, grad] = cofiCostFunc(params, Y, R, n_u, n_m, ...
 | 
				
			||||||
 | 
					                             n, 0);
 | 
				
			||||||
 | 
					    out = sprintf('%0.5f ', grad(:));
 | 
				
			||||||
 | 
					  elseif partId == 5
 | 
				
			||||||
 | 
					    [J] = cofiCostFunc(params, Y, R, n_u, n_m, ...
 | 
				
			||||||
 | 
					                       n, 1.5);
 | 
				
			||||||
 | 
					    out = sprintf('%0.5f ', J(:));
 | 
				
			||||||
 | 
					  elseif partId == 6
 | 
				
			||||||
 | 
					    [J, grad] = cofiCostFunc(params, Y, R, n_u, n_m, ...
 | 
				
			||||||
 | 
					                             n, 1.5);
 | 
				
			||||||
 | 
					    out = sprintf('%0.5f ', grad(:));
 | 
				
			||||||
 | 
					  end 
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% ====================== SERVER CONFIGURATION ===========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% ***************** REMOVE -staging WHEN YOU DEPLOY *********************
 | 
				
			||||||
 | 
					function url = site_url()
 | 
				
			||||||
 | 
					  url = 'http://class.coursera.org/ml-007';
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function url = challenge_url()
 | 
				
			||||||
 | 
					  url = [site_url() '/assignment/challenge'];
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function url = submit_url()
 | 
				
			||||||
 | 
					  url = [site_url() '/assignment/submit'];
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% ========================= CHALLENGE HELPERS =========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function src = source(partId)
 | 
				
			||||||
 | 
					  src = '';
 | 
				
			||||||
 | 
					  src_files = sources();
 | 
				
			||||||
 | 
					  if partId <= numel(src_files)
 | 
				
			||||||
 | 
					      flist = src_files{partId};
 | 
				
			||||||
 | 
					      for i = 1:numel(flist)
 | 
				
			||||||
 | 
					          fid = fopen(flist{i});
 | 
				
			||||||
 | 
					          if (fid == -1) 
 | 
				
			||||||
 | 
					            error('Error opening %s (is it missing?)', flist{i});
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					          line = fgets(fid);
 | 
				
			||||||
 | 
					          while ischar(line)
 | 
				
			||||||
 | 
					            src = [src line];            
 | 
				
			||||||
 | 
					            line = fgets(fid);
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					          fclose(fid);
 | 
				
			||||||
 | 
					          src = [src '||||||||'];
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function ret = isValidPartId(partId)
 | 
				
			||||||
 | 
					  partNames = validParts();
 | 
				
			||||||
 | 
					  ret = (~isempty(partId)) && (partId >= 1) && (partId <= numel(partNames) + 1);
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function partId = promptPart()
 | 
				
			||||||
 | 
					  fprintf('== Select which part(s) to submit:\n');
 | 
				
			||||||
 | 
					  partNames = validParts();
 | 
				
			||||||
 | 
					  srcFiles = sources();
 | 
				
			||||||
 | 
					  for i = 1:numel(partNames)
 | 
				
			||||||
 | 
					    fprintf('==   %d) %s [', i, partNames{i});
 | 
				
			||||||
 | 
					    fprintf(' %s ', srcFiles{i}{:});
 | 
				
			||||||
 | 
					    fprintf(']\n');
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  fprintf('==   %d) All of the above \n==\nEnter your choice [1-%d]: ', ...
 | 
				
			||||||
 | 
					          numel(partNames) + 1, numel(partNames) + 1);
 | 
				
			||||||
 | 
					  selPart = input('', 's');
 | 
				
			||||||
 | 
					  partId = str2num(selPart);
 | 
				
			||||||
 | 
					  if ~isValidPartId(partId)
 | 
				
			||||||
 | 
					    partId = -1;
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function [email,ch,signature,auxstring] = getChallenge(email, part)
 | 
				
			||||||
 | 
					  str = urlread(challenge_url(), 'post', {'email_address', email, 'assignment_part_sid', [homework_id() '-' num2str(part)], 'response_encoding', 'delim'});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  str = strtrim(str);
 | 
				
			||||||
 | 
					  r = struct;
 | 
				
			||||||
 | 
					  while(numel(str) > 0)
 | 
				
			||||||
 | 
					    [f, str] = strtok (str, '|');
 | 
				
			||||||
 | 
					    [v, str] = strtok (str, '|');
 | 
				
			||||||
 | 
					    r = setfield(r, f, v);
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  email = getfield(r, 'email_address');
 | 
				
			||||||
 | 
					  ch = getfield(r, 'challenge_key');
 | 
				
			||||||
 | 
					  signature = getfield(r, 'state');
 | 
				
			||||||
 | 
					  auxstring = getfield(r, 'challenge_aux_data');
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function [result, str] = submitSolutionWeb(email, part, output, source)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  result = ['{"assignment_part_sid":"' base64encode([homework_id() '-' num2str(part)], '') '",' ...
 | 
				
			||||||
 | 
					            '"email_address":"' base64encode(email, '') '",' ...
 | 
				
			||||||
 | 
					            '"submission":"' base64encode(output, '') '",' ...
 | 
				
			||||||
 | 
					            '"submission_aux":"' base64encode(source, '') '"' ...
 | 
				
			||||||
 | 
					            '}'];
 | 
				
			||||||
 | 
					  str = 'Web-submission';
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function [result, str] = submitSolution(email, ch_resp, part, output, ...
 | 
				
			||||||
 | 
					                                        source, signature)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  params = {'assignment_part_sid', [homework_id() '-' num2str(part)], ...
 | 
				
			||||||
 | 
					            'email_address', email, ...
 | 
				
			||||||
 | 
					            'submission', base64encode(output, ''), ...
 | 
				
			||||||
 | 
					            'submission_aux', base64encode(source, ''), ...
 | 
				
			||||||
 | 
					            'challenge_response', ch_resp, ...
 | 
				
			||||||
 | 
					            'state', signature};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  str = urlread(submit_url(), 'post', params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  % Parse str to read for success / failure
 | 
				
			||||||
 | 
					  result = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% =========================== LOGIN HELPERS ===========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function [login password] = loginPrompt()
 | 
				
			||||||
 | 
					  % Prompt for password
 | 
				
			||||||
 | 
					  [login password] = basicPrompt();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if isempty(login) || isempty(password)
 | 
				
			||||||
 | 
					    login = []; password = [];
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function [login password] = basicPrompt()
 | 
				
			||||||
 | 
					  login = input('Login (Email address): ', 's');
 | 
				
			||||||
 | 
					  password = input('Password: ', 's');
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function [login password] = quickLogin(login,password)
 | 
				
			||||||
 | 
					  disp(['You are currently logged in as ' login '.']);
 | 
				
			||||||
 | 
					  cont_token = input('Is this you? (y/n - type n to reenter password)','s');
 | 
				
			||||||
 | 
					  if(isempty(cont_token) || cont_token(1)=='Y'||cont_token(1)=='y')
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    [login password] = loginPrompt();
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function [str] = challengeResponse(email, passwd, challenge)
 | 
				
			||||||
 | 
					  str = sha1([challenge passwd]);
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% =============================== SHA-1 ================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function hash = sha1(str)
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  % Initialize variables
 | 
				
			||||||
 | 
					  h0 = uint32(1732584193);
 | 
				
			||||||
 | 
					  h1 = uint32(4023233417);
 | 
				
			||||||
 | 
					  h2 = uint32(2562383102);
 | 
				
			||||||
 | 
					  h3 = uint32(271733878);
 | 
				
			||||||
 | 
					  h4 = uint32(3285377520);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  % Convert to word array
 | 
				
			||||||
 | 
					  strlen = numel(str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  % Break string into chars and append the bit 1 to the message
 | 
				
			||||||
 | 
					  mC = [double(str) 128];
 | 
				
			||||||
 | 
					  mC = [mC zeros(1, 4-mod(numel(mC), 4), 'uint8')];
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  numB = strlen * 8;
 | 
				
			||||||
 | 
					  if exist('idivide')
 | 
				
			||||||
 | 
					    numC = idivide(uint32(numB + 65), 512, 'ceil');
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    numC = ceil(double(numB + 65)/512);
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  numW = numC * 16;
 | 
				
			||||||
 | 
					  mW = zeros(numW, 1, 'uint32');
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  idx = 1;
 | 
				
			||||||
 | 
					  for i = 1:4:strlen + 1
 | 
				
			||||||
 | 
					    mW(idx) = bitor(bitor(bitor( ...
 | 
				
			||||||
 | 
					                  bitshift(uint32(mC(i)), 24), ...
 | 
				
			||||||
 | 
					                  bitshift(uint32(mC(i+1)), 16)), ...
 | 
				
			||||||
 | 
					                  bitshift(uint32(mC(i+2)), 8)), ...
 | 
				
			||||||
 | 
					                  uint32(mC(i+3)));
 | 
				
			||||||
 | 
					    idx = idx + 1;
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  % Append length of message
 | 
				
			||||||
 | 
					  mW(numW - 1) = uint32(bitshift(uint64(numB), -32));
 | 
				
			||||||
 | 
					  mW(numW) = uint32(bitshift(bitshift(uint64(numB), 32), -32));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  % Process the message in successive 512-bit chs
 | 
				
			||||||
 | 
					  for cId = 1 : double(numC)
 | 
				
			||||||
 | 
					    cSt = (cId - 1) * 16 + 1;
 | 
				
			||||||
 | 
					    cEnd = cId * 16;
 | 
				
			||||||
 | 
					    ch = mW(cSt : cEnd);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    % Extend the sixteen 32-bit words into eighty 32-bit words
 | 
				
			||||||
 | 
					    for j = 17 : 80
 | 
				
			||||||
 | 
					      ch(j) = ch(j - 3);
 | 
				
			||||||
 | 
					      ch(j) = bitxor(ch(j), ch(j - 8));
 | 
				
			||||||
 | 
					      ch(j) = bitxor(ch(j), ch(j - 14));
 | 
				
			||||||
 | 
					      ch(j) = bitxor(ch(j), ch(j - 16));
 | 
				
			||||||
 | 
					      ch(j) = bitrotate(ch(j), 1);
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    % Initialize hash value for this ch
 | 
				
			||||||
 | 
					    a = h0;
 | 
				
			||||||
 | 
					    b = h1;
 | 
				
			||||||
 | 
					    c = h2;
 | 
				
			||||||
 | 
					    d = h3;
 | 
				
			||||||
 | 
					    e = h4;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    % Main loop
 | 
				
			||||||
 | 
					    for i = 1 : 80
 | 
				
			||||||
 | 
					      if(i >= 1 && i <= 20)
 | 
				
			||||||
 | 
					        f = bitor(bitand(b, c), bitand(bitcmp(b), d));
 | 
				
			||||||
 | 
					        k = uint32(1518500249);
 | 
				
			||||||
 | 
					      elseif(i >= 21 && i <= 40)
 | 
				
			||||||
 | 
					        f = bitxor(bitxor(b, c), d);
 | 
				
			||||||
 | 
					        k = uint32(1859775393);
 | 
				
			||||||
 | 
					      elseif(i >= 41 && i <= 60)
 | 
				
			||||||
 | 
					        f = bitor(bitor(bitand(b, c), bitand(b, d)), bitand(c, d));
 | 
				
			||||||
 | 
					        k = uint32(2400959708);
 | 
				
			||||||
 | 
					      elseif(i >= 61 && i <= 80)
 | 
				
			||||||
 | 
					        f = bitxor(bitxor(b, c), d);
 | 
				
			||||||
 | 
					        k = uint32(3395469782);
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      t = bitrotate(a, 5);
 | 
				
			||||||
 | 
					      t = bitadd(t, f);
 | 
				
			||||||
 | 
					      t = bitadd(t, e);
 | 
				
			||||||
 | 
					      t = bitadd(t, k);
 | 
				
			||||||
 | 
					      t = bitadd(t, ch(i));
 | 
				
			||||||
 | 
					      e = d;
 | 
				
			||||||
 | 
					      d = c;
 | 
				
			||||||
 | 
					      c = bitrotate(b, 30);
 | 
				
			||||||
 | 
					      b = a;
 | 
				
			||||||
 | 
					      a = t;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    h0 = bitadd(h0, a);
 | 
				
			||||||
 | 
					    h1 = bitadd(h1, b);
 | 
				
			||||||
 | 
					    h2 = bitadd(h2, c);
 | 
				
			||||||
 | 
					    h3 = bitadd(h3, d);
 | 
				
			||||||
 | 
					    h4 = bitadd(h4, e);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  hash = reshape(dec2hex(double([h0 h1 h2 h3 h4]), 8)', [1 40]);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  hash = lower(hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function ret = bitadd(iA, iB)
 | 
				
			||||||
 | 
					  ret = double(iA) + double(iB);
 | 
				
			||||||
 | 
					  ret = bitset(ret, 33, 0);
 | 
				
			||||||
 | 
					  ret = uint32(ret);
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function ret = bitrotate(iA, places)
 | 
				
			||||||
 | 
					  t = bitshift(iA, places - 32);
 | 
				
			||||||
 | 
					  ret = bitshift(iA, places);
 | 
				
			||||||
 | 
					  ret = bitor(ret, t);
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% =========================== Base64 Encoder ============================
 | 
				
			||||||
 | 
					% Thanks to Peter John Acklam
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function y = base64encode(x, eol)
 | 
				
			||||||
 | 
					%BASE64ENCODE Perform base64 encoding on a string.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%   BASE64ENCODE(STR, EOL) encode the given string STR.  EOL is the line ending
 | 
				
			||||||
 | 
					%   sequence to use; it is optional and defaults to '\n' (ASCII decimal 10).
 | 
				
			||||||
 | 
					%   The returned encoded string is broken into lines of no more than 76
 | 
				
			||||||
 | 
					%   characters each, and each line will end with EOL unless it is empty.  Let
 | 
				
			||||||
 | 
					%   EOL be empty if you do not want the encoded string broken into lines.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%   STR and EOL don't have to be strings (i.e., char arrays).  The only
 | 
				
			||||||
 | 
					%   requirement is that they are vectors containing values in the range 0-255.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%   This function may be used to encode strings into the Base64 encoding
 | 
				
			||||||
 | 
					%   specified in RFC 2045 - MIME (Multipurpose Internet Mail Extensions).  The
 | 
				
			||||||
 | 
					%   Base64 encoding is designed to represent arbitrary sequences of octets in a
 | 
				
			||||||
 | 
					%   form that need not be humanly readable.  A 65-character subset
 | 
				
			||||||
 | 
					%   ([A-Za-z0-9+/=]) of US-ASCII is used, enabling 6 bits to be represented per
 | 
				
			||||||
 | 
					%   printable character.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%   Examples
 | 
				
			||||||
 | 
					%   --------
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%   If you want to encode a large file, you should encode it in chunks that are
 | 
				
			||||||
 | 
					%   a multiple of 57 bytes.  This ensures that the base64 lines line up and
 | 
				
			||||||
 | 
					%   that you do not end up with padding in the middle.  57 bytes of data fills
 | 
				
			||||||
 | 
					%   one complete base64 line (76 == 57*4/3):
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%   If ifid and ofid are two file identifiers opened for reading and writing,
 | 
				
			||||||
 | 
					%   respectively, then you can base64 encode the data with
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%      while ~feof(ifid)
 | 
				
			||||||
 | 
					%         fwrite(ofid, base64encode(fread(ifid, 60*57)));
 | 
				
			||||||
 | 
					%      end
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%   or, if you have enough memory,
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%      fwrite(ofid, base64encode(fread(ifid)));
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%   See also BASE64DECODE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%   Author:      Peter John Acklam
 | 
				
			||||||
 | 
					%   Time-stamp:  2004-02-03 21:36:56 +0100
 | 
				
			||||||
 | 
					%   E-mail:      pjacklam@online.no
 | 
				
			||||||
 | 
					%   URL:         http://home.online.no/~pjacklam
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   if isnumeric(x)
 | 
				
			||||||
 | 
					      x = num2str(x);
 | 
				
			||||||
 | 
					   end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   % make sure we have the EOL value
 | 
				
			||||||
 | 
					   if nargin < 2
 | 
				
			||||||
 | 
					      eol = sprintf('\n');
 | 
				
			||||||
 | 
					   else
 | 
				
			||||||
 | 
					      if sum(size(eol) > 1) > 1
 | 
				
			||||||
 | 
					         error('EOL must be a vector.');
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					      if any(eol(:) > 255)
 | 
				
			||||||
 | 
					         error('EOL can not contain values larger than 255.');
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					   end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   if sum(size(x) > 1) > 1
 | 
				
			||||||
 | 
					      error('STR must be a vector.');
 | 
				
			||||||
 | 
					   end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   x   = uint8(x);
 | 
				
			||||||
 | 
					   eol = uint8(eol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   ndbytes = length(x);                 % number of decoded bytes
 | 
				
			||||||
 | 
					   nchunks = ceil(ndbytes / 3);         % number of chunks/groups
 | 
				
			||||||
 | 
					   nebytes = 4 * nchunks;               % number of encoded bytes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   % add padding if necessary, to make the length of x a multiple of 3
 | 
				
			||||||
 | 
					   if rem(ndbytes, 3)
 | 
				
			||||||
 | 
					      x(end+1 : 3*nchunks) = 0;
 | 
				
			||||||
 | 
					   end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   x = reshape(x, [3, nchunks]);        % reshape the data
 | 
				
			||||||
 | 
					   y = repmat(uint8(0), 4, nchunks);    % for the encoded data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | 
				
			||||||
 | 
					   % Split up every 3 bytes into 4 pieces
 | 
				
			||||||
 | 
					   %
 | 
				
			||||||
 | 
					   %    aaaaaabb bbbbcccc ccdddddd
 | 
				
			||||||
 | 
					   %
 | 
				
			||||||
 | 
					   % to form
 | 
				
			||||||
 | 
					   %
 | 
				
			||||||
 | 
					   %    00aaaaaa 00bbbbbb 00cccccc 00dddddd
 | 
				
			||||||
 | 
					   %
 | 
				
			||||||
 | 
					   y(1,:) = bitshift(x(1,:), -2);                  % 6 highest bits of x(1,:)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   y(2,:) = bitshift(bitand(x(1,:), 3), 4);        % 2 lowest bits of x(1,:)
 | 
				
			||||||
 | 
					   y(2,:) = bitor(y(2,:), bitshift(x(2,:), -4));   % 4 highest bits of x(2,:)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   y(3,:) = bitshift(bitand(x(2,:), 15), 2);       % 4 lowest bits of x(2,:)
 | 
				
			||||||
 | 
					   y(3,:) = bitor(y(3,:), bitshift(x(3,:), -6));   % 2 highest bits of x(3,:)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   y(4,:) = bitand(x(3,:), 63);                    % 6 lowest bits of x(3,:)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | 
				
			||||||
 | 
					   % Now perform the following mapping
 | 
				
			||||||
 | 
					   %
 | 
				
			||||||
 | 
					   %   0  - 25  ->  A-Z
 | 
				
			||||||
 | 
					   %   26 - 51  ->  a-z
 | 
				
			||||||
 | 
					   %   52 - 61  ->  0-9
 | 
				
			||||||
 | 
					   %   62       ->  +
 | 
				
			||||||
 | 
					   %   63       ->  /
 | 
				
			||||||
 | 
					   %
 | 
				
			||||||
 | 
					   % We could use a mapping vector like
 | 
				
			||||||
 | 
					   %
 | 
				
			||||||
 | 
					   %   ['A':'Z', 'a':'z', '0':'9', '+/']
 | 
				
			||||||
 | 
					   %
 | 
				
			||||||
 | 
					   % but that would require an index vector of class double.
 | 
				
			||||||
 | 
					   %
 | 
				
			||||||
 | 
					   z = repmat(uint8(0), size(y));
 | 
				
			||||||
 | 
					   i =           y <= 25;  z(i) = 'A'      + double(y(i));
 | 
				
			||||||
 | 
					   i = 26 <= y & y <= 51;  z(i) = 'a' - 26 + double(y(i));
 | 
				
			||||||
 | 
					   i = 52 <= y & y <= 61;  z(i) = '0' - 52 + double(y(i));
 | 
				
			||||||
 | 
					   i =           y == 62;  z(i) = '+';
 | 
				
			||||||
 | 
					   i =           y == 63;  z(i) = '/';
 | 
				
			||||||
 | 
					   y = z;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 | 
				
			||||||
 | 
					   % Add padding if necessary.
 | 
				
			||||||
 | 
					   %
 | 
				
			||||||
 | 
					   npbytes = 3 * nchunks - ndbytes;     % number of padding bytes
 | 
				
			||||||
 | 
					   if npbytes
 | 
				
			||||||
 | 
					      y(end-npbytes+1 : end) = '=';     % '=' is used for padding
 | 
				
			||||||
 | 
					   end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   if isempty(eol)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      % reshape to a row vector
 | 
				
			||||||
 | 
					      y = reshape(y, [1, nebytes]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      nlines = ceil(nebytes / 76);      % number of lines
 | 
				
			||||||
 | 
					      neolbytes = length(eol);          % number of bytes in eol string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      % pad data so it becomes a multiple of 76 elements
 | 
				
			||||||
 | 
					      y = [y(:) ; zeros(76 * nlines - numel(y), 1)];
 | 
				
			||||||
 | 
					      y(nebytes + 1 : 76 * nlines) = 0;
 | 
				
			||||||
 | 
					      y = reshape(y, 76, nlines);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      % insert eol strings
 | 
				
			||||||
 | 
					      eol = eol(:);
 | 
				
			||||||
 | 
					      y(end + 1 : end + neolbytes, :) = eol(:, ones(1, nlines));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      % remove padding, but keep the last eol string
 | 
				
			||||||
 | 
					      m = nebytes + neolbytes * (nlines - 1);
 | 
				
			||||||
 | 
					      n = (76+neolbytes)*nlines - neolbytes;
 | 
				
			||||||
 | 
					      y(m+1 : n) = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      % extract and reshape to row vector
 | 
				
			||||||
 | 
					      y = reshape(y, 1, m+neolbytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   % output is a character array
 | 
				
			||||||
 | 
					   y = char(y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										20
									
								
								ex8/submitWeb.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								ex8/submitWeb.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					% submitWeb Creates files from your code and output for web submission.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%   If the submit function does not work for you, use the web-submission mechanism.
 | 
				
			||||||
 | 
					%   Call this function to produce a file for the part you wish to submit. Then,
 | 
				
			||||||
 | 
					%   submit the file to the class servers using the "Web Submission" button on the 
 | 
				
			||||||
 | 
					%   Programming Exercises page on the course website.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					%   You should call this function without arguments (submitWeb), to receive
 | 
				
			||||||
 | 
					%   an interactive prompt for submission; optionally you can call it with the partID
 | 
				
			||||||
 | 
					%   if you so wish. Make sure your working directory is set to the directory 
 | 
				
			||||||
 | 
					%   containing the submitWeb.m file and your assignment files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function submitWeb(partId)
 | 
				
			||||||
 | 
					  if ~exist('partId', 'var') || isempty(partId)
 | 
				
			||||||
 | 
					    partId = [];
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  submit(partId, 1);
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										20
									
								
								ex8/visualizeFit.m
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								ex8/visualizeFit.m
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					function visualizeFit(X, mu, sigma2)
 | 
				
			||||||
 | 
					%VISUALIZEFIT Visualize the dataset and its estimated distribution.
 | 
				
			||||||
 | 
					%   VISUALIZEFIT(X, p, mu, sigma2) 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.
 | 
				
			||||||
 | 
					%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[X1,X2] = meshgrid(0:.5:35); 
 | 
				
			||||||
 | 
					Z = multivariateGaussian([X1(:) X2(:)],mu,sigma2);
 | 
				
			||||||
 | 
					Z = reshape(Z,size(X1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					plot(X(:, 1), X(:, 2),'bx');
 | 
				
			||||||
 | 
					hold on;
 | 
				
			||||||
 | 
					% Do not plot if there are infinities
 | 
				
			||||||
 | 
					if (sum(isinf(Z)) == 0)
 | 
				
			||||||
 | 
					    contour(X1, X2, Z, 10.^(-20:3:0)');
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					hold off;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
		Reference in a new issue