Weighted Optimization for CP Tensor Decomposition with Incomplete Data
We explain how to use the CP Weighted Optimization (CP-WOPT) method implemented in cp_wopt. The method is described in the following article:
- E. Acar, D. M. Dunlavy, T. G. Kolda and M. Mørup, Scalable Tensor Factorizations for Incomplete Data, Chemometrics and Intelligent Laboratory Systems, 106(1):41-56, 2011, http://dx.doi.org/10.1016/j.chemolab.2010.08.004.
Contents
- Third-party optimization software
- Important Information
- Create an example problem with missing data.
- Create initial guess using 'nvecs'
- Call the cp_wopt method
- Check the output
- Evaluate the output
- Create a SPARSE example problem with missing data.
- Create initial guess using 'nvecs'
- Call the cp_wopt method
- Check the output
- Evaluate the output
Third-party optimization software
The cp_wopt method uses third-party optimization software to do the optimization. You can use either
The remainder of these instructions assume L-BFGS-B is being used. See here for instructions on using cp_wopt with Poblano.
Important Information
It is critical to zero out the values in the missing entries of the data tensor. This can be done by calling cp_wopt(X.*P,P,...). This is a frequent source of errors in using this method.
Create an example problem with missing data.
Here we have 25% missing data and 10% noise.
R = 2; info = create_problem('Size', [15 10 5], 'Num_Factors', R, ... 'M', 0.25, 'Noise', 0.10); X = info.Data; P = info.Pattern; M_true= info.Soln;
Create initial guess using 'nvecs'
M_init = create_guess('Data', X, 'Num_Factors', R, ... 'Factor_Generator', 'nvecs');
Call the cp_wopt method
Here is an example call to the cp_opt method. By default, each iteration prints the least squares fit function value (being minimized) and the norm of the gradient.
[M,~,output] = cp_wopt(X, P, R, 'init', M_init);
Running CP-WOPT... Time for zeroing out masked entries of data tensor is 1.26e-03 seconds. (If zeroing is done in preprocessing, set 'skip_zeroing' to true.) Iter 10, f(x) = 3.484657e+01, ||grad||_infty = 1.44e+01 Iter 20, f(x) = 2.686975e+00, ||grad||_infty = 1.68e-01 Iter 30, f(x) = 2.681928e+00, ||grad||_infty = 1.75e-03 Iter 34, f(x) = 2.681928e+00, ||grad||_infty = 2.50e-04
Check the output
It's important to check the output of the optimization method. In particular, it's worthwhile to check the exit message for any problems. The message CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH means that it has converged because the function value stopped improving.
exitmsg = output.ExitMsg
exitmsg = 'CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH.'
Evaluate the output
We can "score" the similarity of the model computed by CP and compare that with the truth. The score function on ktensor's gives a score in [0,1] with 1 indicating a perfect match. Because we have noise, we do not expect the fit to be perfect. See doc score for more details.
scr = score(M,M_true)
scr = 0.9977
Create a SPARSE example problem with missing data.
Here we have 95% missing data and 10% noise.
R = 2; info = create_problem('Size', [150 100 50], 'Num_Factors', R, ... 'M', 0.95, 'Sparse_M', true, 'Noise', 0.10); X = info.Data; P = info.Pattern; M_true= info.Soln;
Create initial guess using 'nvecs'
M_init = create_guess('Data', X, 'Num_Factors', R, ... 'Factor_Generator', 'nvecs');
Call the cp_wopt method
[M,~,output] = cp_wopt(X, P, R, 'init', M_init);
Running CP-WOPT... Time for zeroing out masked entries of data tensor is 4.33e-02 seconds. (If zeroing is done in preprocessing, set 'skip_zeroing' to true.) Iter 10, f(x) = 5.028631e+02, ||grad||_infty = 6.58e+00 Iter 20, f(x) = 4.969471e+02, ||grad||_infty = 1.73e+00 Iter 30, f(x) = 4.878141e+02, ||grad||_infty = 1.30e+01 Iter 40, f(x) = 4.563805e+02, ||grad||_infty = 2.24e+01 Iter 50, f(x) = 4.379043e+02, ||grad||_infty = 8.96e+00 Iter 60, f(x) = 4.127368e+02, ||grad||_infty = 2.07e+01 Iter 70, f(x) = 9.426906e+01, ||grad||_infty = 1.29e+01 Iter 80, f(x) = 8.293402e+01, ||grad||_infty = 4.32e-01 Iter 90, f(x) = 8.290516e+01, ||grad||_infty = 7.58e-02 Iter 99, f(x) = 8.290503e+01, ||grad||_infty = 1.25e-02
Check the output
exitmsg = output.ExitMsg
exitmsg = 'CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH.'
Evaluate the output
scr = score(M,M_true)
scr = 0.9983