Inference and comparison

Inference must preserve the model, scale, covariance estimator, approximation, degrees-of-freedom method, and nuisance-parameter treatment that generated it.

Fixed-effect covariance

Fitted results retain fixed_effect_names and, when calculated, fixed_effect_covariance in result.extra. This supports transparent Wald standard errors and linear functions.

For a contrast vector \(c\),

\[ \widehat{\Delta}=c^T\widehat{\beta}, \qquad \operatorname{SE}(\widehat{\Delta}) =\sqrt{c^T\widehat{\operatorname{Var}}(\widehat{\beta})c}. \]

Build contrasts against the archived coefficient ordering, not an assumed column order.

MMRM linear inference

pymixef.backends.mmrm.linear_inference() (aliases pymixef.backends.mmrm.estimated_marginal_means() and pymixef.backends.mmrm.contrasts()) evaluates named linear functions of fixed effects with the selected, explicitly labeled degrees-of-freedom path.

Current labels distinguish:

  • residual degrees of freedom;

  • Satterthwaite delta-method;

  • KR-inspired calculations where available.

KR-inspired output is not described as exact Kenward–Roger. A confirmatory analysis should prespecify target visits, contrasts, multiplicity handling, and DF method.

Bootstrap

pymixef.inference.bootstrap() performs deterministic row or cluster resampling through a caller-supplied fit function.

from pymixef import bootstrap, fit

def refit(sample):
    return fit("y ~ x + (1 | subject)", sample, method="reml")

boot = bootstrap(
    refit,
    data,
    n_replicates=500,
    seed=2026,
    cluster="subject",
    checkpoint="bootstrap.json",
    resume=True,
)
print(boot.intervals(level=0.95).to_dict())

The result retains successful and failed replicate accounting plus percentile intervals. Cluster resampling should match the independent sampling unit; resampling rows inside a clustered design generally answers a different question.

Compare a result to a reference

pymixef.compare.compare() creates a structured pymixef.compare.ComparisonResult:

comparison = pymixef.compare(
    result,
    reference=reference_payload,
    mapping={"treatment[treated]": "treatment"},
    conventions={"likelihood": "normalized"},
)
print(comparison.to_dict())

Parameter mapping and likelihood conventions are explicit. Likelihood/AIC comparisons are refused when conventions are incompatible.

ML and REML comparisons

  • Use ML rather than REML to compare models with different fixed-effect spaces under the usual nested-model reasoning.

  • REML objectives from different fixed-effect designs do not share the same integrated fixed-effect constant and should not be compared as if they did.

  • Covariance-structure comparisons and boundary cases require design-specific care; a naive chi-square reference may be inappropriate.

Effect scale

  • Gaussian identity-link coefficients are on the response scale.

  • Logit coefficients are conditional log odds; exponentiation gives conditional odds ratios.

  • Log-link coefficients become conditional multiplicative ratios after exponentiation.

  • Transforming an interval endpoint-by-endpoint is appropriate for monotone transforms but does not turn a conditional estimand into a marginal one.

API map