Skip to main content

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):

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

avbirt-0.2.0.tar.gz (69.3 kB view details)

Uploaded Source

Built Distribution

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

avbirt-0.2.0-py3-none-any.whl (52.1 kB view details)

Uploaded Python 3

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

Hashes for avbirt-0.2.0.tar.gz
Algorithm Hash digest
SHA256 0d4c0ecaebb2e29956782d5417855e84d85d436fa966a0ed65234d2499bdfa83
MD5 f0a0a0c28cbe2e485a296b4f7b67bb3a
BLAKE2b-256 17c32192a1340b8fedc8764c539da1f57fd796399a091d411dfcb4489880f5ff

See more details on using hashes here.

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

Hashes for avbirt-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 068916d9fdce6efc2115b432c7f87f28185e23630796749803efcc82ff95e82a
MD5 144a60fb7f4b9401566bdce17cf51d90
BLAKE2b-256 b1fc018dd0b8657dcc8029fa8113ff148878fc2f0781a40704262c14df96de26

See more details on using hashes here.

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