Skip to main content

Bernoulli (binary) mean-parameterized NMF (NBMF) w/ Majorization–Minimization (MM)

Project description

nbmf‑mm — Mean‑parameterized Bernoulli NMF via Majorization–Minimization

CI PyPI version License: MIT

nbmf‑mm implements mean‑parameterized Bernoulli matrix factorization (\Theta = W H \in (0,1)^{M\times N}) with a Majorization–Minimization (MM) solver, following Magron & Févotte (2022). It exposes a scikit‑learn‑style API and two symmetric orientations:

  • orientation="beta-dir" (default; Original Paper Setting)
    W rows sum to 1 (simplex constraint); H is continuous in [0,1] with Beta prior
    This matches Magron & Févotte (2022)

  • orientation="dir-beta" (Symmetric Alternative)
    W is continuous in [0,1] with Beta prior; H columns sum to 1 (simplex constraint)
    Mathematically equivalent to "beta-dir" on V.T

Projection choices for the simplex‑constrained factor:

  • projection_method="normalize" (default; theory‑first) – paper‑exact multiplicative step with the /N (or /M) normalizer that preserves the simplex in exact arithmetic and enjoys the classical MM monotonicity guarantee.

  • projection_method="duchi" (fast) – Euclidean projection to the simplex (Duchi et al., 2008) performed after the multiplicative step. This is typically near‑identical to "normalize" numerically, but the formal MM monotonicity guarantee applies to "normalize".

Masked training (matrix completion) is supported: only observed entries contribute to the likelihood and updates. In the simplex steps the paper‑exact /N (or /M) normalizer is naturally replaced by per‑row (or per‑column) observed counts, preserving the simplex under masking.


Installation

pip install nbmf-mm

From source:

pip install "git+https://github.com/siddC/nbmf_mm"

Optional extras:

# scikit-learn integration & NNDSVD-style init (if you enable it later)
pip install "nbmf-mm[sklearn]"

# docs build stack
pip install "nbmf-mm[docs]"

Quick Start

import numpy as np
from nbmf_mm import NBMF

rng = np.random.default_rng(0)
X = (rng.random((100, 500)) < 0.25).astype(float)   # binary {0,1} or probabilities in [0,1]

# Theory-first default: monotone MM with paper-exact normalizer
model = NBMF(n_components=6, orientation="beta-dir",
             alpha=1.2, beta=1.2, random_state=0).fit(X)

W = model.W_                 # shape (n_samples, n_components)
H = model.components_        # shape (n_components, n_features)
Xhat = model.inverse_transform(W)  # probabilities in (0,1)

# Transform new data using fixed components H
Y_new = (rng.random((10, 500)) < 0.25).astype(float)
W_new = model.transform(Y_new)     # shape (10, n_components)

# Masked training / hold-out validation
mask = (rng.random(X.shape) < 0.9).astype(float)  # observe 90% of entries
model = NBMF(n_components=20).fit(X, mask=mask)

print("score (−NLL per observed entry):", model.score(X, mask=mask))
print("perplexity:", model.perplexity(X, mask=mask))

To use the fast projection alternative:

model = NBMF(n_components=6, orientation="beta-dir",
             projection_method="duchi", random_state=0).fit(X)

Mathematical Formulations

Both orientations solve the Bernoulli likelihood: V ~ Bernoulli(sigmoid(W @ H))

Orientation: beta-dir (Matches paper's primary formulation)

  • W: Rows lie on probability simplex (sum to 1)
  • H: Continuous in [0,1] with Beta(α, β) prior
  • Use this to reproduce paper experiments

Orientation: dir-beta (Symmetric formulation)

  • W: Continuous in [0,1] with Beta(α, β) prior
  • H: Columns lie on probability simplex (sum to 1)
  • Mathematically equivalent to beta-dir on V.T

Why two orientations?

Different interpretability needs:

  • beta-dir: W rows are mixture weights over latent factors; H captures factor-feature associations
  • dir-beta: H columns are mixture weights over latent aspects; W captures sample-aspect propensities

Both solve the same mean-parameterized factorization with symmetric geometric constraints.


API Hightlihts

NBMF( n_components: int, orientation: {"dir-beta","beta-dir"} = "beta-dir", alpha: float = 1.2, beta: float = 1.2, projection_method: {"normalize","duchi"} = "normalize", max_iter: int = 2000, tol: float = 1e-6, random_state: int | None = None, n_init: int = 1,

accepted for compatibility (currently unused in core Python impl)

use_numexpr: bool = False, use_numba: bool = False, projection_backend: str = "auto", )


Reproducibility

  • Set random_state (int) for reproducible initialization.
  • Use n_init > 1 to run several random restarts and keep the best NLL.

Reproducing Magron & Févotte (2022)

To reproduce the results from the original paper, use these settings:

from nbmf_mm import NBMF

# Use beta-dir to match paper exactly
model = NBMF(
    n_components=10,
    orientation="beta-dir",
    alpha=1.2,
    beta=1.2,
    max_iter=500,
    tol=1e-5
)
model.fit(X)

# W rows will sum to 1, H will be continuous

Run the reproduction scripts:

python examples/reproduce_magron2022.py
python examples/display_figures.py

References

  • Simplex projection (default):
    • J. Duchi, S. Shalev‑Shwartz, Y. Singer, T. Chandra (2008). Efficient Projections onto the ℓ₁‑Ball for Learning in High Dimensions. ICML 2008.

    • W. Wang, M. Á. Carreira‑Perpiñán (2013). Projection onto the probability simplex: An efficient algorithm with a simple proof, and an application. arXiv:1309.1541.

    • Bayesian NBMF (related, slower but fully Bayesian):

      • See the NBMF project by alumbreras for reference implementations of Bayesian variants.

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

nbmf_mm-0.1.4.tar.gz (14.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nbmf_mm-0.1.4-py3-none-any.whl (11.9 kB view details)

Uploaded Python 3

File details

Details for the file nbmf_mm-0.1.4.tar.gz.

File metadata

  • Download URL: nbmf_mm-0.1.4.tar.gz
  • Upload date:
  • Size: 14.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nbmf_mm-0.1.4.tar.gz
Algorithm Hash digest
SHA256 abedae25f1a563190996325025827d38362f47b9563c61d98fb85fbff19206fb
MD5 4db4fb7c2b76eb939aa3ab458c10bb86
BLAKE2b-256 116c29db02cb083752decb34b3a093d3e0a0353236eca6d57baadca1d88a6253

See more details on using hashes here.

Provenance

The following attestation bundles were made for nbmf_mm-0.1.4.tar.gz:

Publisher: release.yml on siddC/nbmf_mm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nbmf_mm-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: nbmf_mm-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 11.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nbmf_mm-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 8b9ac6686d966341607a7bcca41e2c1f410ecfc16fa83a67016abc205fef1bcd
MD5 eb9c6a7ba33730d1061132d1e52fa21f
BLAKE2b-256 deee90a150a81e3be91811b730fa4608315a5b02fc803a70fd33e21768f4a2de

See more details on using hashes here.

Provenance

The following attestation bundles were made for nbmf_mm-0.1.4-py3-none-any.whl:

Publisher: release.yml on siddC/nbmf_mm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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