Demo: Matrix Completion
This short demo shows how to use TFOCS to perform nuclear norm minimization. Nuclear norm minimization is used for recovering all the entries of a partially observed low-rank matrix.
Contents
Setup a problem
rng(234923); % for reproducible results N = 16; % the matrix is N x N r = 2; % the rank of the matrix df = 2*N*r - r^2; % degrees of freedom of a N x N rank r matrix nSamples = 3*df; % number of observed entries % For this demo, we will use a matrix with integer entries % because it will make displaying the matrix easier. iMax = 5; X = randi(iMax,N,r)*randi(iMax,r,N); % Our target matrix
Now suppose we only see a few entries of X. Let “Omega” be the set of observed entries
rPerm = randperm(N^2); % use "randsample" if you have the stats toolbox
omega = sort( rPerm(1:nSamples) );
Print out the observed matrix in a nice format. The “NaN” entries represent unobserved values. The goal of this demo is to find out what those values are!
Y = nan(N);
Y(omega) = X(omega);
disp('The "NaN" entries represent unobserved values');
disp(Y)
The "NaN" entries represent unobserved values 30 NaN 24 8 12 14 12 NaN 22 NaN NaN 10 14 24 20 NaN 30 21 NaN 11 21 NaN 12 21 NaN 15 17 NaN 8 15 23 NaN NaN 9 NaN NaN 9 NaN NaN NaN 7 9 8 7 5 NaN 11 6 35 NaN NaN 10 NaN NaN NaN NaN 23 NaN 17 13 15 26 24 NaN NaN 9 9 5 NaN NaN NaN NaN NaN 9 8 NaN NaN 9 11 NaN NaN 11 19 7 NaN 13 10 11 17 19 12 9 11 19 17 NaN 45 24 30 NaN NaN 29 18 NaN 25 30 NaN 19 17 30 32 NaN NaN NaN 21 NaN 15 18 12 15 18 21 15 12 12 21 21 12 25 11 NaN 7 11 13 10 11 17 19 12 9 NaN 19 NaN NaN NaN 13 11 7 13 16 8 NaN 8 11 11 NaN NaN 11 15 8 45 24 30 14 24 29 18 24 25 30 23 19 17 NaN 32 18 NaN 15 21 9 NaN 18 12 15 18 21 15 12 NaN 21 21 12 25 NaN 13 9 17 NaN 10 17 NaN 13 14 13 7 13 19 10 40 20 28 12 20 NaN 16 20 NaN NaN NaN 16 16 NaN 28 16 NaN NaN 18 10 18 22 12 NaN 14 NaN 16 14 10 NaN 22 12 25 11 19 7 11 NaN 10 NaN NaN NaN NaN 9 11 19 17 NaN
Matrix completion via TFOCS
We use nuclear norm relaxation. There are strong theorems that show this relaxation will usually give you the exact original low-rank matrix provided that certain conditions hold. However, these conditions are generally not possible to check ‘a priori’, so I cannot guarantee that this will work. But by choosing enough measurements, it becomes increasingly likely to work.
% Add TFOCS to your path (modify this line appropriately): addpath ~/Dropbox/TFOCS/ observations = X(omega); % the observed entries mu = .001; % smoothing parameter % The solver runs in seconds tic Xk = solver_sNuclearBP( {N,N,omega}, observations, mu ); toc
Auslender & Teboulle's single-projection method Iter Objective |dx|/|x| step ----+---------------------------------- 100 | +3.54125e+02 1.68e-04 1.32e-03 200 | +3.54125e+02 7.42e-07 1.77e-03* 251 | +3.54125e+02 5.41e-09 2.28e-03* Finished: Step size tolerance reached Elapsed time is 1.289716 seconds.
To display the recovered matrix, let’s round it to the nearest .0001 so that it displays nicely:
disp('Recovered matrix (rounding to nearest .0001):') disp( round(Xk*10000)/10000 ) % and for reference, here is the original matrix: disp('Original matrix:') disp( X ) % The relative error (without the rounding) is quite low: fprintf('Relative error, no rounding: %.8f%%\n', norm(X-Xk,'fro')/norm(X,'fro')*100 );
Recovered matrix (rounding to nearest .0001): 30 12 24 8 12 14 12 12 22 24 14 10 14 24 20 12 30 21 15 11 21 26 12 21 10 15 17 16 8 15 23 12 15 9 9 5 9 11 6 9 7 9 8 7 5 9 11 6 35 16 26 10 16 19 14 16 23 26 17 13 15 26 24 14 15 9 9 5 9 11 6 9 7 9 8 7 5 9 11 6 25 11 19 7 11 13 10 11 17 19 12 9 11 19 17 10 45 24 30 14 24 29 18 24 25 30 23 19 17 30 32 18 30 15 21 9 15 18 12 15 18 21 15 12 12 21 21 12 25 11 19 7 11 13 10 11 17 19 12 9 11 19 17 10 20 13 11 7 13 16 8 13 8 11 11 10 6 11 15 8 45 24 30 14 24 29 18 24 25 30 23 19 17 30 32 18 30 15 21 9 15 18 12 15 18 21 15 12 12 21 21 12 25 17 13 9 17 21 10 17 9 13 14 13 7 13 19 10 40 20 28 12 20 24 16 20 24 28 20 16 16 28 28 16 30 18 18 10 18 22 12 18 14 18 16 14 10 18 22 12 25 11 19 7 11 13 10 11 17 19 12 9 11 19 17 10 Original matrix: 30 12 24 8 12 14 12 12 22 24 14 10 14 24 20 12 30 21 15 11 21 26 12 21 10 15 17 16 8 15 23 12 15 9 9 5 9 11 6 9 7 9 8 7 5 9 11 6 35 16 26 10 16 19 14 16 23 26 17 13 15 26 24 14 15 9 9 5 9 11 6 9 7 9 8 7 5 9 11 6 25 11 19 7 11 13 10 11 17 19 12 9 11 19 17 10 45 24 30 14 24 29 18 24 25 30 23 19 17 30 32 18 30 15 21 9 15 18 12 15 18 21 15 12 12 21 21 12 25 11 19 7 11 13 10 11 17 19 12 9 11 19 17 10 20 13 11 7 13 16 8 13 8 11 11 10 6 11 15 8 45 24 30 14 24 29 18 24 25 30 23 19 17 30 32 18 30 15 21 9 15 18 12 15 18 21 15 12 12 21 21 12 25 17 13 9 17 21 10 17 9 13 14 13 7 13 19 10 40 20 28 12 20 24 16 20 24 28 20 16 16 28 28 16 30 18 18 10 18 22 12 18 14 18 16 14 10 18 22 12 25 11 19 7 11 13 10 11 17 19 12 9 11 19 17 10 Relative error, no rounding: 0.00000410%
Published with MATLAB® 7.12