Importance-Weighted Adversarial Variational Bayes for high-dimensional Item Factor Analysis
Project description
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file avbirt-0.2.0.tar.gz.
File metadata
- Download URL: avbirt-0.2.0.tar.gz
- Upload date:
- Size: 69.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d4c0ecaebb2e29956782d5417855e84d85d436fa966a0ed65234d2499bdfa83
|
|
| MD5 |
f0a0a0c28cbe2e485a296b4f7b67bb3a
|
|
| BLAKE2b-256 |
17c32192a1340b8fedc8764c539da1f57fd796399a091d411dfcb4489880f5ff
|
File details
Details for the file avbirt-0.2.0-py3-none-any.whl.
File metadata
- Download URL: avbirt-0.2.0-py3-none-any.whl
- Upload date:
- Size: 52.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
068916d9fdce6efc2115b432c7f87f28185e23630796749803efcc82ff95e82a
|
|
| MD5 |
144a60fb7f4b9401566bdce17cf51d90
|
|
| BLAKE2b-256 |
b1fc018dd0b8657dcc8029fa8113ff148878fc2f0781a40704262c14df96de26
|