Mixed-effects models in Python: LMM, GLMM, CLMM, and Cox frailty with crossed random effects, validated against R
Project description
interlace
Pure-Python mixed-effects modelling library — linear (LMM), generalised (GLMM), ordinal (CLMM), and survival (Cox frailty) — validated against R's lme4, glmer, ordinal, and coxme.
Designed as a drop-in replacement for statsmodels.MixedLM in diagnostics pipelines that require crossed grouping factors (e.g. (1|worker) + (1|company)), which statsmodels does not support.
Installation
pip install interlace-lme
Requires Python ≥ 3.10.
For materially faster random-slopes LMM and GLMM fits (~3-10x), install the [fast] extra to pull in scikit-sparse (CHOLMOD):
pip install 'interlace-lme[fast]'
CHOLMOD requires SuiteSparse system libraries (libsuitesparse-dev on Debian/Ubuntu, brew install suite-sparse on macOS). Without [fast], fits fall back to SuperLU and you'll see a one-shot warning at fit time on the slow path.
Quick start
import pandas as pd
from interlace import fit
result = fit(
formula="score ~ hours_studied + prior_gpa",
data=df,
groups=["student_id", "school_id"], # crossed random intercepts
)
print(result.fe_params) # fixed-effect coefficients
print(result.variance_components) # per-factor variance components
print(result.scale) # residual variance σ²
groups accepts a single string (one random intercept) or a list (crossed intercepts). The first entry is the primary grouping factor.
Model types
Linear mixed models (LMM)
from interlace import fit
result = fit(
formula="score ~ hours_studied + prior_gpa",
data=df,
groups=["student_id", "school_id"],
method="REML", # or "ML" for likelihood-ratio tests
df_method="satterthwaite", # or "kenward-roger"
)
Supports crossed and nested random intercepts, random slopes ((1 + x | g)), observation-level weights, AR(1) and compound-symmetry residual correlation structures, and Satterthwaite or Kenward-Roger denominator degrees of freedom.
Generalised linear mixed models (GLMM)
from interlace import glmer
result = glmer(
formula="incidence / size ~ period",
data=df,
family="binomial", # or "poisson", "gaussian", "negativebinomial"
groups="herd",
weights=df["size"].values,
)
Families: binomial, Poisson, Gaussian, NB1, NB2, Beta, Gamma, zero-inflated Poisson/NB2, hurdle Poisson, zero-one-inflated Beta. Supports Laplace approximation and adaptive Gauss-Hermite quadrature.
Cumulative link mixed models (CLMM)
from interlace import clmm
result = clmm(
formula="rating ~ condition",
data=df,
groups="subject",
)
Ordinal regression with random effects, matching R's ordinal::clmm().
Cox frailty models
from interlace import coxme
result = coxme(
formula="Surv(time, event) ~ treatment + age",
data=df,
groups="centre",
)
Cox proportional hazards with Gaussian frailty, matching R's coxme::coxme().
Diagnostics
from interlace import hlm_resid, leverage, hlm_influence, hlm_augment
resid_df = hlm_resid(result, type="conditional") # or "marginal"
lev = leverage(result) # hat-matrix diagonal
infl = hlm_influence(result, level=1) # Cook's D, MDFFITS, etc.
aug = hlm_augment(result) # data + residuals + influence
# Plotting (all return plotnine.ggplot objects)
from interlace import plot_resid, plot_influence, dotplot_diag
plot_resid(resid_df, type="resid_vs_fitted")
plot_influence(infl, measure="cooks_d")
dotplot_diag(infl, variable="cooks_d", cutoff="internal")
statsmodels compatibility
CrossedLMEResult exposes the same interface as statsmodels.MixedLMResults so it can be used as a drop-in in downstream code that accesses fe_params, resid, scale, fittedvalues, random_effects, predict(), and model.exog / model.groups / model.data.frame.
hlm_resid, hlm_influence, and hlm_augment all accept either a CrossedLMEResult or a statsmodels MixedLMResults object.
Parity with R
Results are validated against R reference implementations to the following tolerances:
| Model type | R reference | Fixed effects | Variance components |
|---|---|---|---|
| LMM | lme4::lmer() |
abs diff < 1e-4 | rel diff < 5% |
| GLMM | lme4::glmer() |
abs diff < 1e-3 | rel diff < 5% |
| CLMM | ordinal::clmm() |
abs diff < 1e-3 | rel diff < 5% |
| Cox frailty | coxme::coxme() |
abs diff < 1e-3 | rel diff < 10% |
| AR(1) / CS | nlme::lme() |
abs diff < 1e-3 | rel diff < 5% |
Contributing
Bug reports, documentation fixes, and new features are welcome — see CONTRIBUTING.md for how to get started. To open an issue or ask a question, use the GitHub issue tracker.
Attribution
- lme4 — the reference implementation for mixed-effects models in R; interlace targets parity with
lme4::lmer()andlme4::glmer(). - ordinal — R package for cumulative link models; interlace's
clmm()targets parity withordinal::clmm(). - coxme — R package for Cox models with random effects; interlace's
coxme()targets parity withcoxme::coxme(). - nlme — R package for linear mixed models with correlation structures; AR(1) and CS validation benchmarks.
- HLMdiag — the R package whose diagnostics API (
hlm_resid,hlm_influence,hlm_augment,dotplot_diag) interlace replicates in Python.
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 interlace_lme-0.3.2.tar.gz.
File metadata
- Download URL: interlace_lme-0.3.2.tar.gz
- Upload date:
- Size: 12.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b6da8143288565a227f9be807452ec9720dc172e7d61f5d9f6f194542707834
|
|
| MD5 |
697b2171c140124f98cb140ffac456df
|
|
| BLAKE2b-256 |
5e3344c4e358332cf870dcbcabbef06dc1c7cf211d24fa9528c5d4ddec22f168
|
Provenance
The following attestation bundles were made for interlace_lme-0.3.2.tar.gz:
Publisher:
publish.yml on heliopais/interlace
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
interlace_lme-0.3.2.tar.gz -
Subject digest:
6b6da8143288565a227f9be807452ec9720dc172e7d61f5d9f6f194542707834 - Sigstore transparency entry: 1966938884
- Sigstore integration time:
-
Permalink:
heliopais/interlace@0ba8c8d0a203a43a280d2e95e5290f8e04938f71 -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/heliopais
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0ba8c8d0a203a43a280d2e95e5290f8e04938f71 -
Trigger Event:
push
-
Statement type:
File details
Details for the file interlace_lme-0.3.2-py3-none-any.whl.
File metadata
- Download URL: interlace_lme-0.3.2-py3-none-any.whl
- Upload date:
- Size: 172.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d2f2a4f362d2ea88bc4b750cba67f4135ff12116036e062fcf3db04b4c8f3d7
|
|
| MD5 |
c38f0cf028a7d7f72aeb377a4520f807
|
|
| BLAKE2b-256 |
8d73be86936acef38b3cf88c78fcc650783bd6a8c6a8895ed1fa39a8ac5dee16
|
Provenance
The following attestation bundles were made for interlace_lme-0.3.2-py3-none-any.whl:
Publisher:
publish.yml on heliopais/interlace
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
interlace_lme-0.3.2-py3-none-any.whl -
Subject digest:
3d2f2a4f362d2ea88bc4b750cba67f4135ff12116036e062fcf3db04b4c8f3d7 - Sigstore transparency entry: 1966939029
- Sigstore integration time:
-
Permalink:
heliopais/interlace@0ba8c8d0a203a43a280d2e95e5290f8e04938f71 -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/heliopais
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0ba8c8d0a203a43a280d2e95e5290f8e04938f71 -
Trigger Event:
push
-
Statement type: