Package: matcouply
Learning coupled matrix factorizations with PythonMatCoupLy is a Python library for learning coupled matrix factorizations with flexible constraints and regularization.
For a quick introduction to coupled matrix factorization and PARAFAC2 see theonline documentation.InstallationTo install MatCoupLy and all MIT-compatible dependencies from PyPI, you can runpip install matcouplyIf you also want to enable total variation regularization, you need to install all components, which comes with a GPL-v3 lisencepip install matcouply[gpl]AboutMatCoupLy is a Python library that adds support for coupled matrix factorization inTensorLy. For optimization, MatCoupLy uses
alternating updates with the alternating direction method of multipliers (AO-ADMM),
which allows you to fit coupled matrix factorization (and PARAFAC2) models with flexible
constraints in any mode of your data [1, 2]. Currently, MatCoupLy supports the NumPy and
PyTorch backends of TensorLy.ExampleBelow is a simulated example, where a set of 15 non-negative coupled matrices are generated and
decomposed using a non-negative PARAFAC2 factorization with an L1 penalty onC, constraining
the maximum norm of theAandBᵢmatrices and unimodality constraints on the component
vectors in theBᵢmatrices. For more examples, see theGallery of examplesin theonline documentation.importmatplotlib.pyplotaspltimportnumpyasnpfrommatcouply.dataimportget_simple_simulated_datafrommatcouply.decompositionimportcmf_aoadmmnoisy_matrices,cmf=get_simple_simulated_data(noise_level=0.2,random_state=1)rank=cmf.rankweights,(A,B_is,C)=cmf# Decompose the datasetestimated_cmf=cmf_aoadmm(noisy_matrices,rank=rank,non_negative=True,# Constrain all components to be non-negativel1_penalty={2:0.1},# Sparsity on Cl2_norm_bound=[1,1,0],# Norm of A and B_i-component vectors less than 1parafac2=True,# Enforce PARAFAC2 constraintunimodal={1:True},# Unimodality (one peak) on the B_i component vectorsconstant_feasibility_penalty=True,# Must be set to apply l2_norm_penalty (row-penalty) on A. See documentation for more detailsverbose=-1,# Negative verbosity level for minimal (nonzero) printoutsrandom_state=0,# A seed can be given similar to how it's done in TensorLy)est_weights,(est_A,est_B_is,est_C)=estimated_cmf# Code to display the resultsdefnormalize(M):returnM/np.linalg.norm(M,axis=0)fig,axes=plt.subplots(2,3,figsize=(5,2))axes[0,0].plot(normalize(A))axes[0,1].plot(normalize(B_is[0]))axes[0,2].plot(normalize(C))axes[1,0].plot(normalize(est_A))axes[1,1].plot(normalize(est_B_is[0]))axes[1,2].plot(normalize(est_C))axes[0,0].set_title(r"$\mathbf{A}$")axes[0,1].set_title(r"$\mathbf{B}_0$")axes[0,2].set_title(r"$\mathbf{C}$")axes[0,0].set_ylabel("True")axes[1,0].set_ylabel("Estimated")foraxinaxes.ravel():ax.set_yticks([])# Components can be aribtrarily scaledforaxinaxes[0]:ax.set_xticks([])# Remove xticks from upper rowplt.savefig("figures/readme_components.png",dpi=300)All regularization penalties (including regs list):
* Mode 0:
   - <'matcouply.penalties.L2Ball' with aux_init='random_uniform', dual_init='random_uniform', norm_bound=1, non_negativity=True)>
* Mode 1:
   - <'matcouply.penalties.Parafac2' with svd='truncated_svd', aux_init='random_uniform', dual_init='random_uniform', update_basis_matrices=True, update_coordinate_matrix=True, n_iter=1)>
   - <'matcouply.penalties.Unimodality' with aux_init='random_uniform', dual_init='random_uniform', non_negativity=True)>
   - <'matcouply.penalties.L2Ball' with aux_init='random_uniform', dual_init='random_uniform', norm_bound=1, non_negativity=True)>
* Mode 2:
   - <'matcouply.penalties.L1Penalty' with aux_init='random_uniform', dual_init='random_uniform', reg_strength=0.1, non_negativity=True)>
converged in 218 iterations: FEASIBILITY GAP CRITERION AND RELATIVE LOSS CRITERION SATISFIEDReferences[1]: Roald M, Schenker C, Cohen JE, Acar E PARAFAC2 AO-ADMM: Constraints in all modes. EUSIPCO (2021).[2]: Roald M, Schenker C, Calhoun VD, Adali T, Bro R, Cohen JE, Acar E An AO-ADMM approach to constraining PARAFAC2 on all modes (2022). Accepted for publication in SIAM Journal on Mathematics of Data Science, arXiv preprint arXiv:2110.01278.