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. 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
pip install avbirt # core estimator + presets
pip install avbirt[tune] # + automatic tuner (optuna)
pip install avbirt[examples] # + notebook deps (deepirtools, matplotlib, ...)
From source (development):
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
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:
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]):
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.
Examples
The 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— multivariate normal latent ability distribution (N=5000, M=70, C=5, P=7).simulation_multimodal.ipynb— 3-mode multimodal latent ability distribution (N=5000, M=45, C=3, P=3).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 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:
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
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.
Citation
If you use this package in your research, please cite:
@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.
Metadata
Release files for avbirt 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| avbirt-0.2.0.tar.gz | 69.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| avbirt-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 121.4 kB
Release files / avbirt-0.2.0.tar.gz
| Download URL | avbirt-0.2.0.tar.gz |
|---|---|
| Size | 69.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0d4c0ecaebb2e29956782d5417855e84d85d436fa966a0ed65234d2499bdfa83
|
|
BLAKE2b-256 checksum How to use checksums |
17c32192a1340b8fedc8764c539da1f57fd796399a091d411dfcb4489880f5ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / avbirt-0.2.0-py3-none-any.whl
| Download URL | avbirt-0.2.0-py3-none-any.whl |
|---|---|
| Size | 52.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
068916d9fdce6efc2115b432c7f87f28185e23630796749803efcc82ff95e82a
|
|
BLAKE2b-256 checksum How to use checksums |
b1fc018dd0b8657dcc8029fa8113ff148878fc2f0781a40704262c14df96de26
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Security for avbirt 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.