Skip to main content

Regularized coupled matrix factorisation with AO-ADMM

Project description

Learning coupled matrix factorizations with Python

Tests Coverage Documentation Status https://zenodo.org/badge/402865945.svg https://img.shields.io/badge/code%20style-black-000000.svg

MatCoupLy 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 the online documentation.

Installation

To install MatCoupLy and all MIT-compatible dependencies from PyPI, you can run

pip install matcouply

If you also want to enable total variation regularization, you need to install all components, which comes with a GPL-v3 lisence

pip install matcouply[gpl]

About

Illustration of a coupled matrix factorization

MatCoupLy is a Python library that adds support for coupled matrix factorization in TensorLy. 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.

Example

Below 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 on C, constraining the maximum norm of the A and Bᵢ matrices and unimodality constraints on the component vectors in the Bᵢ matrices. For more examples, see the Gallery of examples in the online documentation.

import matplotlib.pyplot as plt
import numpy as np

from matcouply.data import get_simple_simulated_data
from matcouply.decomposition import cmf_aoadmm

noisy_matrices, cmf = get_simple_simulated_data(noise_level=0.2, random_state=1)
rank = cmf.rank
weights, (A, B_is, C) = cmf

# Decompose the dataset
estimated_cmf = cmf_aoadmm(
    noisy_matrices,
    rank=rank,
    non_negative=True,  # Constrain all components to be non-negative
    l1_penalty={2: 0.1},  # Sparsity on C
    l2_norm_bound=[1, 1, 0],  # Norm of A and B_i-component vectors less than 1
    parafac2=True,  # Enforce PARAFAC2 constraint
    unimodal={1: True},  # Unimodality (one peak) on the B_i component vectors
    constant_feasibility_penalty=True,  # Must be set to apply l2_norm_penalty (row-penalty) on A. See documentation for more details
    verbose=-1,  # Negative verbosity level for minimal (nonzero) printouts
    random_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 results
def normalize(M):
    return M / 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")

for ax in axes.ravel():
    ax.set_yticks([])  # Components can be aribtrarily scaled
for ax in axes[0]:
    ax.set_xticks([])  # Remove xticks from upper row

plt.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 SATISFIED
Plot of simulated and estimated components

References

  • [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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

matcouply-0.1.6.tar.gz (1.6 MB view details)

Uploaded Source

Built Distribution

matcouply-0.1.6-py3-none-any.whl (2.3 MB view details)

Uploaded Python 3

File details

Details for the file matcouply-0.1.6.tar.gz.

File metadata

  • Download URL: matcouply-0.1.6.tar.gz
  • Upload date:
  • Size: 1.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for matcouply-0.1.6.tar.gz
Algorithm Hash digest
SHA256 58ad0871abd0c6933a76023d947bb1803c22a5946284c3c0dbe24d8d2f8fa43a
MD5 c9fb3464bb5ff989701f07d0372fa271
BLAKE2b-256 39ce63ec5ae13beb308e1b86039b9f1588bfc5018302ef3bd43b12f399220e56

See more details on using hashes here.

File details

Details for the file matcouply-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: matcouply-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 2.3 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for matcouply-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 b536271774807da452a236b65bb652dcd268f9ed8fb1753ae618f0020883dc97
MD5 94b97d692bc99984c4605e80dff2263b
BLAKE2b-256 0e586f519a2238d44b8e50e8a654b4b68e921bcdfa800d7c0ba34a0f58183fb3

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page