Metadata-Version: 2.4
Name: manocca
Version: 2.0.1
Summary: MANOCCA: Multivariate ANalysis of Conditional CovAriance
Author: Christophe Boetto, Hugues Aschard
License-Expression: MIT
Project-URL: Homepage, https://gitlab.pasteur.fr/statistical-genetics/manocca
Project-URL: Publication, https://academic.oup.com/bib/article/25/4/bbae272/7690346
Project-URL: Bug Tracker, https://gitlab.pasteur.fr/statistical-genetics/manocca/-/issues
Keywords: statistics,multivariate,covariance,MANOVA,bioinformatics,genomics
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.21
Requires-Dist: scipy>=1.8
Requires-Dist: pandas>=1.4
Requires-Dist: scikit-learn>=1.0
Requires-Dist: joblib>=1.1
Requires-Dist: tqdm>=4.64
Dynamic: license-file

# MANOCCA

**Multivariate ANalysis of Conditional CovAriance**

MANOCCA tests whether a predictor *X* is associated with the **covariance structure** of multivariate outcomes *Y*, adjusting for covariates *C*:

> Cov(Y) ~ X + C

Unlike MANOVA (which tests mean effects) or univariate approaches, MANOCCA isolates changes in correlations/covariances between outcomes. The test is orthogonal to mean and variance effects.

**Reference:** Boetto C. & Aschard H. (2024). *Briefings in Bioinformatics*, 25(4).  
https://academic.oup.com/bib/article/25/4/bbae272/7690346

---

## Installation

```bash
pip install manocca
```

Or with conda (once the feedstock is available on conda-forge):

```bash
conda install -c conda-forge manocca
```

---

## Quick start

```python
import numpy as np
from manocca import MANOCCA, MANOVA, UNIVARIATE, Explainer

rng = np.random.default_rng(42)
N, K = 1000, 10

X = rng.binomial(1, 0.4, (N, 1)).astype(float)   # binary predictor
C = rng.standard_normal((N, 3))                   # covariates
Y = rng.standard_normal((N, K))                   # outcomes

# Inject a covariance effect: Y0 and Y1 become correlated when X=1
mask = X.flatten() == 1
Y[mask, 0] += 1.5 * Y[mask, 1]

# Test Cov(Y) ~ X + C
model = MANOCCA(predictors=X, outputs=Y, covariates=C, n_comp=20)
model.test()
print(f"MANOCCA p-value: {model.p[0, 0]:.4e}")   # should be significant
```

---

## Classes

| Class | Tests | Description |
|-------|-------|-------------|
| `MANOCCA` | Cov(Y) ~ X + C | Core covariance test |
| `MANOVA` | Mean(Y) ~ X + C | Classical multivariate mean test |
| `UNIVARIATE` | Y_j ~ X + C | Univariate baseline (per outcome) |
| `Explainer` | — | Interprets a fitted MANOCCA model |

### MANOCCA

```python
model = MANOCCA(
    predictors,          # ndarray or DataFrame (N, n_p)
    outputs,             # ndarray or DataFrame (N, k), k >= 2
    covariates=None,     # ndarray or DataFrame (N, n_c), optional
    n_comp=None,         # number of PCA components (default: k)
    apply_qt=True,       # quantile-transform products before PCA
    use_pca=True,        # reduce with PCA (recommended for large k)
    corr_bias=False,     # subtract additive mean-effect bias
    n_jobs=1,            # parallel workers (-1 = all cores)
)
model.test()
model.p                  # ndarray (n_p, 1) — p-values per predictor
```

### Explainer

```python
exp = Explainer(model)

# P-value vs. number of PCA components
p_curve, grid = exp.power_pc_kept("predictor_name", grid=range(1, 21))

# Which pairwise covariances drive the signal?
importances = exp.feature_importances("predictor_name", n_comp=10)

# Per-outcome contribution
contrib = exp.split_contribution(importances)
```

---

## Algorithm

1. Compute all *k(k−1)/2* pairwise products of (optionally QT-transformed) outcomes.
2. Reduce dimensionality with PCA; apply a second QT to the components.
3. Residualize the components against covariates *C*.
4. Run a Wilks' Lambda MANOVA of the residuals against each predictor in *X*.

See the paper for details on the bias-correction mode (`corr_bias=True`), which makes the test orthogonal to additive mean effects without QT or PCA.

---

## Citation

```bibtex
@article{boetto2024manocca,
  author  = {Boetto, Christophe and Aschard, Hugues},
  title   = {{MANOCCA}: Multivariate ANalysis of Conditional CovAriance},
  journal = {Briefings in Bioinformatics},
  volume  = {25},
  number  = {4},
  year    = {2024},
  doi     = {10.1093/bib/bbae272},
}
```

---

## License

MIT © Christophe Boetto, Hugues Aschard
