Reproducibility and cross-language parity¶
Notes for PyMICE development, validation, and publication.
Random number generation (R vs Python)¶
Summary¶
By default, PyMICE uses NumPy's PCG64 generator (rng="numpy"). Stochastic imputations therefore differ from R mice even when the same numeric seed is supplied.
For vignette replication and cross-checks against R, pass rng="r" to use R's default Mersenne-Twister stream (via a bundled Rscript server). With rng="r", pmm, norm, and norm.nob on the bundled nhanes dataset match R reference outputs bit-for-bit under seed=123.
Choosing an RNG backend¶
from pymice import mice, RngBackend
# Default: NumPy PCG64 (fast, independent of R)
imp = mice(data, seed=123)
# Explicit backends
imp = mice(data, seed=123, rng="numpy") # same as default
imp = mice(data, seed=123, rng="legacy") # NumPy MT19937 (not R-identical)
imp = mice(data, seed=123, rng="r") # R default MT (requires Rscript)
# Or pass your own numpy Generator
imp = mice(data, rng=np.random.default_rng(42))
rng value |
Engine | R parity | Notes |
|---|---|---|---|
"numpy" (default) |
NumPy PCG64 | No | Recommended for new Python workflows |
"legacy" |
NumPy MT19937 | No | Alternative NumPy stream; seed required |
"r" |
R stats RNG |
Yes for PMM/norm paths | Requires R; slower (subprocess) |
numpy.random.Generator |
User-supplied | Depends | Full control for custom workflows |
Set PYMICE_R_PAN=0 to disable the optional R pan backend for 2l.pan independently of rng.
Optional R / sklearn backends (independent of rng)¶
These backends call R or scikit-learn for specific imputation methods. They auto-activate when dependencies are available unless disabled.
| Variable | Methods | Requires |
|---|---|---|
PYMICE_R_PAN |
2l.pan |
R + pan |
PYMICE_R_LMER |
2l.lmer, 2l.bin |
R + mice + lme4 + MASS |
PYMICE_R_AMPUTE |
ampute() chain |
R + mice + jsonlite |
PYMICE_SKLEARN |
lasso.*, lda |
pip install pymice-fcs[ml] |
Set any variable to 0 to force the NumPy/Python fallback.
R prerequisites (rng="r" only)¶
When rng="r" is requested, PyMICE checks for Rscript and CRAN packages mice and pan.
The check does not run for the default rng="numpy" backend.
from pymice import ensure_r_prerequisites, check_r_prerequisites
status = check_r_prerequisites() # inspect only
ensure_r_prerequisites(install=True) # run bundled installer if needed
Environment variables:
| Variable | Effect |
|---|---|
PYMICE_AUTO_INSTALL_R=1 |
Auto-install R/packages when rng="r" in library code |
PYMICE_SKIP_R_INSTALL=1 |
Disable auto-install in vignettes and ensure_r_prerequisites(install=True) |
Vignette runners (devtools/run_vignettes.py) call the installer by default before executing demos.
The chosen backend is stored on the returned mids object as rng_backend and reused by continue_imputation().
Why imputations differ by default¶
| Factor | R mice |
PyMICE (rng="numpy") |
|---|---|---|
| RNG engine | Mersenne Twister (default) | NumPy PCG64 |
| Draw ordering | Fixed by R sampler() call sequence |
Matched structurally, not byte-for-byte |
| PMM donors | matchindex C++ with R .Random.seed |
Python port of matchindex; independent RNG stream |
Even one divergent draw during initialization or an early FCS iteration changes all subsequent imputations.
What does match¶
- Deterministic methods (e.g.
mean):nhanesgolden tests match R within machine precision (atol ≤ 1e-12) with any backend. - Stochastic methods with
rng="r":pmm,norm,norm.nobonnhanesmatch R goldens (tests/goldens/r/). - Observed cells: Never altered; always identical to input.
- Pooling (Rubin 1987 + Barnard–Rubin df): Independent of imputation RNG when given the same per-imputation estimates and standard errors;
pool.scalarmatches R reference formulas exactly.
Statistical interpretation¶
MICE treats imputation as a proper stochastic step (Rubin, 1987). Valid inference depends on:
- Correct FCS / univariate imputation models
- Correct Rubin pooling of estimates, not of raw multiply imputed rows
- Adequate number of imputations
m
Re-running R mice with a different seed also yields different imputations but valid pooled inference. PyMICE with rng="numpy" is in the same class: algorithmically equivalent, RNG-independent.
Validation strategy used in this project¶
- Structural parity: FCS loop, predictor matrix, visit sequence, method dispatch aligned with JSS (2011) and R
mice3.19 behavior. - Deterministic goldens:
meanimputation vs R onnhanes. - R-RNG goldens:
pmm/norm/norm.nobvs R whenrng="r". - Session chain helpers:
devtools/lib/vignette_rng.pymirrors R tutorial draw order for V01–V06; goldens refreshed viaregenerate_draw_order_goldens.py,regenerate_v05_goldens.py,regenerate_v06_goldens.py. - Stochastic checks: Observed data preserved; imputations finite and in plausible ranges; PMM donors drawn from observed values.
- Pooling goldens:
pool.scalarandlm(bmi ~ hyp + chl)workflow withmethod="mean"(stable imputations) vs R. - Multilevel tolerance:
2l.norm/2l.panmoment checks within ~0.15 on V05 steps 21–26 (documented partial).
Reporting recommendations (publication)¶
When describing PyMICE results alongside or in comparison to R mice:
- Report
pymiceversion,m,maxit, methods,rngbackend, and pooling rule (Rubin 1987 / Barnard–Rubin 1999). - State that default PyMICE uses NumPy PCG64; use
rng="r"only when R-matching imputations are required. - Where comparison to R is shown, prefer pooled estimates, SEs, and FMI over cell-level imputation tables unless
mean, fixeddata_init, orrng="r"is used. - Cite van Buuren & Groothuis-Oudshoorn (2011) for MICE methodology and Rubin (1987) / Barnard & Rubin (1999) for pooling.
- Full release checklist and BibTeX:
PUBLICATION.md.
References¶
- Barnard, J., & Rubin, D. B. (1999). Small sample degrees of freedom with multiple imputation. Biometrika, 86(4), 948–955.
- Rubin, D. B. (1987). Multiple Imputation for Nonresponse in Surveys. Wiley.
- van Buuren, S., & Groothuis-Oudshoorn, K. (2011). mice: Multivariate Imputation by Chained Equations in R. Journal of Statistical Software, 45(3), 1–67.