Metadata-Version: 2.4
Name: avbirt
Version: 0.2.0
Summary: Importance-Weighted Adversarial Variational Bayes for high-dimensional Item Factor Analysis
Author: Nanyu Luo, Feng Ji
License: MIT License
        
        Copyright (c) 2025 Nanyu Luo and Feng Ji
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Repository, https://github.com/Feng-Ji-Lab/AVBIRT
Project-URL: Issues, https://github.com/Feng-Ji-Lab/AVBIRT/issues
Project-URL: Paper, https://doi.org/10.1017/psy.2025.10059
Project-URL: PubMed, https://pubmed.ncbi.nlm.nih.gov/41216666/
Keywords: item-factor-analysis,item-response-theory,variational-inference,adversarial-learning,psychometrics,graded-response-model
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
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
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: torch>=2.0
Requires-Dist: pyro-ppl>=1.8
Requires-Dist: numpy>=1.24
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Provides-Extra: tune
Requires-Dist: optuna>=3.0; extra == "tune"
Requires-Dist: pandas; extra == "tune"
Requires-Dist: scipy; extra == "tune"
Provides-Extra: examples
Requires-Dist: scikit-learn; extra == "examples"
Requires-Dist: deepirtools; extra == "examples"
Requires-Dist: jupyter; extra == "examples"
Requires-Dist: matplotlib; extra == "examples"
Requires-Dist: pandas; extra == "examples"
Requires-Dist: seaborn; extra == "examples"
Requires-Dist: setuptools<81; extra == "examples"
Provides-Extra: benchmarks
Requires-Dist: pyyaml; extra == "benchmarks"
Requires-Dist: pandas; extra == "benchmarks"
Requires-Dist: scipy; extra == "benchmarks"
Requires-Dist: deepirtools; extra == "benchmarks"
Requires-Dist: setuptools<81; extra == "benchmarks"
Provides-Extra: all
Requires-Dist: optuna>=3.0; extra == "all"
Requires-Dist: pandas; extra == "all"
Requires-Dist: scipy; extra == "all"
Requires-Dist: scikit-learn; extra == "all"
Requires-Dist: deepirtools; extra == "all"
Requires-Dist: jupyter; extra == "all"
Requires-Dist: matplotlib; extra == "all"
Requires-Dist: seaborn; extra == "all"
Requires-Dist: setuptools<81; extra == "all"
Dynamic: license-file

# avbirt

**Importance-Weighted Adversarial Variational Bayes for Item Factor Analysis**

`avbirt` is the reference implementation accompanying:

> Luo N, Ji F. *Generative Adversarial Networks for High-Dimensional Item Factor
> Analysis: A Deep Adversarial Learning Algorithm.* **Psychometrika.** 2025 Nov 11;
> 90(5):1–24. doi: [10.1017/psy.2025.10059](https://doi.org/10.1017/psy.2025.10059).
> PMID: 41216666; PMCID: PMC12805202.

It fits a confirmatory or exploratory Item Factor Analysis (IFA) model to ordinal
response data using the Graded Response Model (GRM), combining:

- **Importance-Weighted ELBO (IW-ELBO)** — a tighter bound on the marginal
  log-likelihood than the standard ELBO, approaching MML as the number of
  importance weights `R → ∞`.
- **Adversarial Variational Bayes (AVB)** — the KL divergence between the
  variational posterior and the prior is estimated by a discriminator network
  rather than computed in closed form.
- **Adaptive Contrast (AC)** — normalises posterior samples before passing them
  to the discriminator, making the adversarial task tractable in high dimensions.
- **Doubly Reparameterized Gradients (DReG)** — reduces encoder gradient variance.

---

## Installation

```bash
pip install avbirt                 # core estimator + presets
pip install avbirt[tune]           # + automatic tuner (optuna)
pip install avbirt[examples]       # + notebook deps (deepirtools, matplotlib, ...)
```

From source (development):

```bash
git clone https://github.com/Feng-Ji-Lab/AVBIRT.git
cd AVBIRT
pip install -e ".[dev,tune,examples]"
```

**Requirements:** Python ≥ 3.9, PyTorch ≥ 2.0, Pyro ≥ 1.8. A CUDA-capable GPU
is strongly recommended for realistic model sizes.

---

## Quick Start

```python
import torch
from avbirt import IWAVB_estimator

# Response matrix: N respondents × M items, integer responses in {0, ..., C-1}
dataset = torch.randint(0, 5, (1000, 45))

# Confirmatory IFA: define a binary Q-matrix (M items × P factors)
Q = torch.zeros(45, 3)
Q[:15, 0] = 1
Q[15:30, 1] = 1
Q[30:, 2] = 1

estimator = IWAVB_estimator(
    representation_size=3,    # P = 3 latent factors
    num_questions=45,         # M = 45 items
    num_categories=5,         # C = 5 response categories
    num_students=1000,        # N = 1000 respondents
    Q=Q,
)

estimator.fit(dataset, batch_size=32, iw_num=50)

scores   = estimator.predict(dataset)         # (N, P) NumPy array of factor scores
loadings = estimator.get_loadings()           # (M, P) loading matrix
ll       = estimator.log_likelihood(dataset)  # approximate marginal log-likelihood
```

For exploratory IFA (no Q-matrix), simply omit the `Q` argument.

---

## Presets — verified configs in one call

Four hyperparameter presets ship with the package, each a 50-rep-verified winner
from the tuning study. Pick one from your data shape and fit in one call:

```python
from avbirt import IWAVB_estimator, recommend_preset, list_presets

print(list_presets())                              # catalogue + verdicts
name = recommend_preset(N=5000, M=70, C=5, P=7)    # -> "normal"
est = IWAVB_estimator.from_preset(name, num_students=5000, num_questions=70,
                                  num_categories=5, representation_size=7, Q=Q)
est.fit(data)                                       # preset fit kwargs applied
```

| preset | shape (N,M,C,P) | AVBIRT vs IWAVE (50-rep) |
|---|---|---|
| `small` | 1000,20,5,2 | PASS (disc 0.75×, int 0.13×, fcov 1.47×) |
| `normal` | 5000,70,5,7 | PASS (1.29× / 1.37× / 1.51×) |
| `multimodal` | 5000,45,3,3 | PASS median (disc 0.53× med, int 0.86×, fcov 1.46×) |
| `moderate` | 5000,40,5,5 | NEAR-MISS (1.98× / 1.33× / 2.23×) |

Ratios are AVBIRT/IWAVE MSE (50-rep): **< 1 means AVBIRT wins**; a **PASS** verdict means every metric is within 2× of IWAVE (not necessarily better).

---

## Automatic tuner

For data that doesn't match a preset, tune on your own data
(`pip install avbirt[tune]`):

```python
from avbirt import tune

result = tune(data, representation_size=5, num_categories=5, Q=Q, n_trials=50)
est = result.best_estimator        # refit on all data with the winning config
```

By default the tuner maximizes the held-out IW-ELBO (no ground truth needed). In
a simulation study, pass `true_params={"disc": ..., "intercept": ...}` to tune
for parameter recovery instead. See [docs/tuner_and_presets.md](docs/tuner_and_presets.md).

---

## Examples

The [`examples/`](examples/) directory contains executed simulation notebooks
that reproduce the paper's studies, plus an S1–S4 comparison notebook (shipped as
an unexecuted template):

- [`simulation_normal.ipynb`](examples/simulation_normal.ipynb) — multivariate
  normal latent ability distribution (N=5000, M=70, C=5, P=7).
- [`simulation_multimodal.ipynb`](examples/simulation_multimodal.ipynb) — 3-mode
  multimodal latent ability distribution (N=5000, M=45, C=3, P=3).
- [`comparison_S1_S4.ipynb`](examples/comparison_S1_S4.ipynb) — IWAVE-vs-IWAVB
  across all four scenarios (S1–S4): a live single-rep fit plus the cached 50-rep
  results.

Both simulation notebooks compare `avbirt` against the IWAVE baseline from
[`deepirtools`](https://github.com/cjurban/deepirtools) over 3 independent
repetitions and report MSE for discrimination, intercept, ability, and factor
covariance estimates. Per-rep training logs are saved under `examples/logs/`.

To regenerate the notebooks from the source script:

```bash
python examples/make_notebooks.py
```

---

## Package Structure

```
avbirt/
├── __init__.py            ← IWAVB_estimator, tune, presets helpers
├── presets.py             ← canonical S1-S4 presets + recommend_preset/list_presets
├── scenarios.py           ← S1-S4 simulation generators
├── metrics.py             ← parameter-recovery MSE + alignment
├── defaults.py            ← profile registry
├── models/                ← constraints, distributions, grm, networks
├── core/                  ← iwavb (forward), estimator (+ from_preset), init
└── tuner/                 ← tune(), search space, objectives, Optuna driver
```

---

## Running Tests

```bash
pytest                              # full suite
pytest -m "not slow"                # skip end-to-end integration tests
pytest tests/test_constraints.py    # single module
```

---

## Implementation Status

**Beta (0.2.0).** The public API is `IWAVB_estimator` (with `.from_preset`),
`tune`, and the preset helpers (`PRESETS`, `recommend_preset`, `list_presets`).
Internal modules may still change. See [CHANGELOG.md](CHANGELOG.md).

---

## Citation

If you use this package in your research, please cite:

```bibtex
@article{luo2025avbirt,
  author  = {Luo, Nanyu and Ji, Feng},
  title   = {Generative Adversarial Networks for High-Dimensional Item Factor
             Analysis: A Deep Adversarial Learning Algorithm},
  journal = {Psychometrika},
  year    = {2025},
  volume  = {90},
  number  = {5},
  pages   = {1--24},
  doi     = {10.1017/psy.2025.10059},
  pmid    = {41216666},
  pmcid   = {PMC12805202},
}
```

---

## License

Released under the [MIT License](LICENSE).
