bossanova 0.1.0.dev11__tar.gz → 0.1.0.dev12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/.gitignore +2 -1
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/PKG-INFO +1 -1
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/__init__.py +2 -1
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/__init__.py +6 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/builders/__init__.py +10 -2
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/builders/dataframes.py +53 -14
- bossanova-0.1.0.dev12/bossanova/internal/containers/builders/resamples.py +226 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/builders/results.py +29 -6
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/builders/state.py +14 -121
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/schemas.py +30 -32
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/structs/state.py +27 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/__init__.py +0 -4
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/backend/dispatch.py +2 -6
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/backend/jax.py +3 -6
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/design/coding.py +1 -1
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/family/__init__.py +2 -1
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/family/schema.py +7 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/inference/__init__.py +12 -4
- bossanova-0.1.0.dev12/bossanova/internal/maths/inference/multiplicity.py +101 -0
- bossanova-0.1.0.dev12/bossanova/internal/maths/inference/sandwich.py +291 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/inference/welch.py +70 -120
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/linalg/__init__.py +4 -0
- bossanova-0.1.0.dev12/bossanova/internal/maths/linalg/schur.py +97 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/solvers/__init__.py +0 -2
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/solvers/glm.py +2 -81
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/solvers/lmer.py +0 -146
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/__init__.py +6 -6
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/common/__init__.py +4 -2
- bossanova-0.1.0.dev12/bossanova/internal/operations/common/data_utils.py +36 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/common/formula_utils.py +48 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/compare/helpers.py +4 -6
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/diagnostics.py +2 -2
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/fit/__init__.py +2 -4
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/fit/dispatch.py +27 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/fit/glmer.py +13 -57
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/fit/lmer.py +2 -52
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/infer/__init__.py +8 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/infer/asymptotic.py +70 -94
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/infer/bootstrap.py +185 -3
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/infer/cv.py +265 -52
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/infer/mee.py +37 -11
- bossanova-0.1.0.dev12/bossanova/internal/operations/infer/params.py +160 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/infer/permutation.py +15 -16
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/infer/resample_bundle.py +5 -2
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/marginal/__init__.py +2 -2
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/marginal/compute.py +199 -54
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/marginal/conditions.py +13 -45
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/marginal/contrasts.py +48 -19
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/marginal/emm.py +26 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/marginal/inference.py +212 -28
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/marginal/joint_tests.py +154 -10
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/marginal/slopes.py +189 -7
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/resample/core.py +2 -3
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/resample/glmer.py +3 -3
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/core_data.py +100 -90
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/mem.py +1 -4
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/params.py +2 -1
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/model/core.py +217 -500
- bossanova-0.1.0.dev12/bossanova/model/guards.py +201 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/model/summary.py +4 -2
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/pyproject.toml +39 -32
- bossanova-0.1.0.dev11/bossanova/internal/maths/inference/sandwich.py +0 -115
- bossanova-0.1.0.dev11/bossanova/internal/operations/common/classify.py +0 -20
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/LICENSE +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/README.md +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/README.md +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/advertising.csv +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/cake.csv +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/chickweight.csv +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/credit.csv +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/gammas.csv +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/mtcars.csv +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/penguins.csv +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/poker.csv +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/sleep.csv +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/titanic.csv +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/titanic_test.csv +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/data/titanic_train.csv +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/distributions/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/distributions/continuous.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/distributions/discrete.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/distributions/varying.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/expressions.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/builders/data.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/builders/specs.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/structs/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/structs/data.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/structs/display.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/structs/explore.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/structs/formula.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/structs/specs.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/validators.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/backend/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/backend/numpy.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/backend/protocol.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/batching.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/config.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/convergence.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/design/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/design/names.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/design/reference.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/design/z_matrix.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/differentiation.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/distributions/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/distributions/algebra.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/distributions/base.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/distributions/core.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/distributions/derived.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/distributions/factories.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/distributions/plotting.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/distributions/probability.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/family/binomial.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/family/create.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/family/gamma.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/family/gaussian.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/family/links.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/family/poisson.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/family/response.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/family/tdist.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/inference/contrasts.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/inference/diagnostics.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/inference/estimation.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/inference/hypothesis.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/inference/information_criteria.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/inference/profile.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/inference/satterthwaite.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/inference/wald_variance.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/linalg/qr.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/linalg/sparse.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/linalg/svd.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/predict.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/rng.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/solvers/glmer.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/solvers/heuristics.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/solvers/initialization.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/solvers/lambda_builder.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/solvers/lambda_sparse.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/solvers/lambda_template.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/solvers/optimize.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/solvers/pirls_sparse.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/solvers/quadrature.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/tolerances.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/transforms.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/variance.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/maths/weights.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/bundle.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/common/factors.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/compare/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/compare/compare.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/compare/cv.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/compare/deviance.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/compare/f_test.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/compare/lrt.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/compare/lrt_compare.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/compare/refit.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/contrasts.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/convergence.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/fit/glm.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/fit/ols.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/fit/rank.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/design.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/encoding.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/evaluate.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/evaluate_newdata.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/evaluate_transforms.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/helpers.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/parse.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/parser/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/parser/expr.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/parser/parser.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/parser/scanner.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/parser/token.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/formula/random_effects.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/infer/prediction.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/infer/profile.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/infer/satterthwaite_emm.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/infer/simulation.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/marginal/explore.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/marginal/grid.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/marginal/validation.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/predict.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/profile.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/rendering/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/rendering/latex.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/resample/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/resample/common.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/resample/glm.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/resample/lm.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/resample/lm_bca.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/resample/lm_operators.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/resample/lmer.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/resample/mixed.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/resample/results.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/resample/utils.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/simulation/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/simulation/dgp/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/simulation/dgp/generate.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/simulation/dgp/glm.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/simulation/dgp/glmer.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/simulation/dgp/lm.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/simulation/dgp/lmer.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/simulation/harness.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/simulation/metrics.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/simulation/model_sim.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/transforms.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/operations/varying.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/README.md +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/cognition.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/compare.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/core.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/core_protocols.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/core_sizing.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/core_viz.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/dag.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/design.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/fit.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/fit_builders.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/fit_layers.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/helpers.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/lattice.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/layout.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/predict.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/profile.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/ranef.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/relationships.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/resamples.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/resid.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/viz/vif.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/model/__init__.py +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/py.typed +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/tests/bossanova_benchmarks/bootstrap/data/README.md +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/tests/bossanova_benchmarks/insteval/data/README.md +0 -0
- {bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/tests/bossanova_tests/hypothesis/README.md +0 -0
|
@@ -17,7 +17,7 @@ docs/_build/
|
|
|
17
17
|
docs/performance/
|
|
18
18
|
profile_*.py
|
|
19
19
|
benchmarks/
|
|
20
|
-
!bossanova-docs/
|
|
20
|
+
!bossanova-docs/engineering/benchmarks/
|
|
21
21
|
examples/
|
|
22
22
|
papers/
|
|
23
23
|
paper-summaries/
|
|
@@ -64,6 +64,7 @@ dist/
|
|
|
64
64
|
|
|
65
65
|
# Logs
|
|
66
66
|
*.log
|
|
67
|
+
logs/
|
|
67
68
|
|
|
68
69
|
# Refs
|
|
69
70
|
MixedModels.jl/
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# Backend API (must be imported first, before any JAX usage)
|
|
2
2
|
from bossanova.internal.maths.backend import backend, get_backend, set_backend
|
|
3
3
|
|
|
4
|
-
# Configure JAX x64 eagerly if JAX is available
|
|
4
|
+
# Configure JAX x64 eagerly if JAX is available — SINGLE AUTHORITATIVE LOCATION.
|
|
5
5
|
# This MUST happen before any JAX arrays are created anywhere in the codebase.
|
|
6
6
|
# We cannot defer this to lazy loading because submodules (e.g., lmer_core.py)
|
|
7
7
|
# import JAX at module level and would create float32 arrays otherwise.
|
|
8
|
+
# All other modules rely on this having run at import time.
|
|
8
9
|
try:
|
|
9
10
|
import jax
|
|
10
11
|
|
|
@@ -67,8 +67,11 @@ from bossanova.internal.containers.builders import (
|
|
|
67
67
|
build_params_dataframe,
|
|
68
68
|
build_prediction_state,
|
|
69
69
|
build_predictions_dataframe,
|
|
70
|
+
build_mee_resamples,
|
|
71
|
+
build_params_resamples,
|
|
70
72
|
build_resamples_dataframe,
|
|
71
73
|
build_resamples_state,
|
|
74
|
+
extract_mee_names,
|
|
72
75
|
build_simulation_inference_state,
|
|
73
76
|
build_simulation_spec,
|
|
74
77
|
build_simulation_spec_from_formula,
|
|
@@ -117,10 +120,12 @@ __all__ = [
|
|
|
117
120
|
"build_inference_state",
|
|
118
121
|
"build_joint_test_dataframe",
|
|
119
122
|
"build_joint_test_state",
|
|
123
|
+
"build_mee_resamples",
|
|
120
124
|
"build_mee_state",
|
|
121
125
|
"build_model_spec",
|
|
122
126
|
"build_model_spec_from_formula",
|
|
123
127
|
"build_params_dataframe",
|
|
128
|
+
"build_params_resamples",
|
|
124
129
|
"build_prediction_state",
|
|
125
130
|
"build_predictions_dataframe",
|
|
126
131
|
"build_resamples_dataframe",
|
|
@@ -136,5 +141,6 @@ __all__ = [
|
|
|
136
141
|
"build_varying_spread_dataframe",
|
|
137
142
|
"build_varying_spread_state",
|
|
138
143
|
"build_varying_state",
|
|
144
|
+
"extract_mee_names",
|
|
139
145
|
"get_varying_random_terms",
|
|
140
146
|
]
|
{bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/builders/__init__.py
RENAMED
|
@@ -26,6 +26,13 @@ from bossanova.internal.containers.builders.specs import (
|
|
|
26
26
|
build_varying_spec,
|
|
27
27
|
get_varying_random_terms,
|
|
28
28
|
)
|
|
29
|
+
from bossanova.internal.containers.builders.resamples import (
|
|
30
|
+
build_mee_resamples,
|
|
31
|
+
build_params_resamples,
|
|
32
|
+
build_resamples_dataframe,
|
|
33
|
+
build_resamples_state,
|
|
34
|
+
extract_mee_names,
|
|
35
|
+
)
|
|
29
36
|
from bossanova.internal.containers.builders.state import (
|
|
30
37
|
build_cv_state,
|
|
31
38
|
build_fit_state,
|
|
@@ -33,8 +40,6 @@ from bossanova.internal.containers.builders.state import (
|
|
|
33
40
|
build_joint_test_state,
|
|
34
41
|
build_mee_state,
|
|
35
42
|
build_prediction_state,
|
|
36
|
-
build_resamples_dataframe,
|
|
37
|
-
build_resamples_state,
|
|
38
43
|
build_simulation_inference_state,
|
|
39
44
|
build_varying_spread_state,
|
|
40
45
|
build_varying_state,
|
|
@@ -48,10 +53,12 @@ __all__ = [
|
|
|
48
53
|
"build_inference_state",
|
|
49
54
|
"build_joint_test_dataframe",
|
|
50
55
|
"build_joint_test_state",
|
|
56
|
+
"build_mee_resamples",
|
|
51
57
|
"build_mee_state",
|
|
52
58
|
"build_model_spec",
|
|
53
59
|
"build_model_spec_from_formula",
|
|
54
60
|
"build_params_dataframe",
|
|
61
|
+
"build_params_resamples",
|
|
55
62
|
"build_prediction_state",
|
|
56
63
|
"build_predictions_dataframe",
|
|
57
64
|
"build_resamples_dataframe",
|
|
@@ -67,5 +74,6 @@ __all__ = [
|
|
|
67
74
|
"build_varying_spread_dataframe",
|
|
68
75
|
"build_varying_spread_state",
|
|
69
76
|
"build_varying_state",
|
|
77
|
+
"extract_mee_names",
|
|
70
78
|
"get_varying_random_terms",
|
|
71
79
|
]
|
{bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/builders/dataframes.py
RENAMED
|
@@ -19,7 +19,9 @@ from bossanova.internal.containers.schemas import (
|
|
|
19
19
|
Col,
|
|
20
20
|
ParamsAsymp,
|
|
21
21
|
ParamsBase,
|
|
22
|
+
ParamsBoot,
|
|
22
23
|
ParamsCv,
|
|
24
|
+
ParamsPerm,
|
|
23
25
|
VaryingCorrSchema,
|
|
24
26
|
)
|
|
25
27
|
|
|
@@ -56,33 +58,61 @@ def build_params_dataframe(
|
|
|
56
58
|
) -> pl.DataFrame:
|
|
57
59
|
"""Build the ``.params`` DataFrame from fit state.
|
|
58
60
|
|
|
61
|
+
Column set varies by inference method:
|
|
62
|
+
|
|
63
|
+
- **asymp**: all inference columns (p_value last).
|
|
64
|
+
- **boot**: no p_value; df = n_resamples.
|
|
65
|
+
- **perm**: no CIs; df = n_valid_resamples.
|
|
66
|
+
- **cv**: PRE columns only.
|
|
67
|
+
- **None**: term + estimate only.
|
|
68
|
+
|
|
59
69
|
Args:
|
|
60
70
|
bundle: Data bundle containing ``X_names`` (coefficient labels).
|
|
61
71
|
fit: Fit state containing ``coef`` (coefficient estimates).
|
|
62
72
|
params_inference: Optional inference state with SE, CI, p-values.
|
|
63
73
|
|
|
64
74
|
Returns:
|
|
65
|
-
DataFrame with ``term``, ``estimate``, and
|
|
75
|
+
DataFrame with ``term``, ``estimate``, and method-appropriate
|
|
76
|
+
inference columns.
|
|
66
77
|
"""
|
|
67
78
|
terms = list(bundle.X_names)
|
|
68
79
|
estimates = fit.coef.tolist()
|
|
69
80
|
|
|
70
81
|
data: dict[str, list] = {Col.TERM: terms, Col.ESTIMATE: estimates}
|
|
71
82
|
|
|
72
|
-
if params_inference is
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
if params_inference is None:
|
|
84
|
+
return pl.DataFrame(data, schema=ParamsBase)
|
|
85
|
+
|
|
86
|
+
method = params_inference.method
|
|
87
|
+
|
|
88
|
+
if method == "cv":
|
|
89
|
+
data[Col.PRE] = params_inference.pre.tolist()
|
|
90
|
+
data[Col.PRE_SD] = params_inference.pre_sd.tolist()
|
|
91
|
+
return pl.DataFrame(data, schema=ParamsCv)
|
|
92
|
+
|
|
93
|
+
if method == "boot":
|
|
94
|
+
data[Col.SE] = params_inference.se.tolist()
|
|
95
|
+
data[Col.CI_LOWER] = params_inference.ci_lower.tolist()
|
|
96
|
+
data[Col.CI_UPPER] = params_inference.ci_upper.tolist()
|
|
97
|
+
data[Col.STATISTIC] = params_inference.statistic.tolist()
|
|
98
|
+
data[Col.DF] = params_inference.df.tolist()
|
|
99
|
+
return pl.DataFrame(data, schema=ParamsBoot)
|
|
100
|
+
|
|
101
|
+
if method == "perm":
|
|
77
102
|
data[Col.SE] = params_inference.se.tolist()
|
|
78
103
|
data[Col.STATISTIC] = params_inference.statistic.tolist()
|
|
79
104
|
data[Col.DF] = params_inference.df.tolist()
|
|
80
105
|
data[Col.P_VALUE] = params_inference.p_value.tolist()
|
|
81
|
-
data
|
|
82
|
-
data[Col.CI_UPPER] = params_inference.ci_upper.tolist()
|
|
83
|
-
return pl.DataFrame(data, schema=ParamsAsymp)
|
|
106
|
+
return pl.DataFrame(data, schema=ParamsPerm)
|
|
84
107
|
|
|
85
|
-
|
|
108
|
+
# Default: asymptotic (or any unknown method)
|
|
109
|
+
data[Col.SE] = params_inference.se.tolist()
|
|
110
|
+
data[Col.CI_LOWER] = params_inference.ci_lower.tolist()
|
|
111
|
+
data[Col.CI_UPPER] = params_inference.ci_upper.tolist()
|
|
112
|
+
data[Col.STATISTIC] = params_inference.statistic.tolist()
|
|
113
|
+
data[Col.DF] = params_inference.df.tolist()
|
|
114
|
+
data[Col.P_VALUE] = params_inference.p_value.tolist()
|
|
115
|
+
return pl.DataFrame(data, schema=ParamsAsymp)
|
|
86
116
|
|
|
87
117
|
|
|
88
118
|
def build_varying_offsets_dataframe(
|
|
@@ -220,6 +250,7 @@ def build_varying_corr_dataframe(
|
|
|
220
250
|
groups.append(group)
|
|
221
251
|
corrs.append(value)
|
|
222
252
|
|
|
253
|
+
# TODO: are we only limited to 2 effects?
|
|
223
254
|
return pl.DataFrame(
|
|
224
255
|
{
|
|
225
256
|
Col.GROUP: groups,
|
|
@@ -246,19 +277,27 @@ def _infer_group_from_spread(varying_spread: VaryingSpreadState) -> str:
|
|
|
246
277
|
return ""
|
|
247
278
|
|
|
248
279
|
|
|
249
|
-
def build_effects_dataframe(
|
|
280
|
+
def build_effects_dataframe(
|
|
281
|
+
mee: MeeState,
|
|
282
|
+
method: str | None = None,
|
|
283
|
+
) -> pl.DataFrame:
|
|
250
284
|
"""Build the ``.effects`` DataFrame from marginal effects state.
|
|
251
285
|
|
|
286
|
+
Column set varies by inference method: bootstrap excludes ``p_value``,
|
|
287
|
+
permutation excludes ``ci_lower``/``ci_upper``.
|
|
288
|
+
|
|
252
289
|
Args:
|
|
253
290
|
mee: MeeState with grid, estimates, and optional inference.
|
|
291
|
+
method: Inference method (``"asymp"``, ``"boot"``, ``"perm"``,
|
|
292
|
+
or ``None``). Controls which inference columns are included.
|
|
254
293
|
|
|
255
294
|
Returns:
|
|
256
|
-
DataFrame with grid columns, ``estimate``, and
|
|
257
|
-
columns.
|
|
295
|
+
DataFrame with grid columns, ``estimate``, and method-appropriate
|
|
296
|
+
inference columns.
|
|
258
297
|
"""
|
|
259
298
|
result = mee.grid.clone()
|
|
260
299
|
result = result.with_columns(pl.Series(Col.ESTIMATE, mee.estimate))
|
|
261
|
-
return append_inference_columns(result, mee)
|
|
300
|
+
return append_inference_columns(result, mee, method=method)
|
|
262
301
|
|
|
263
302
|
|
|
264
303
|
def build_joint_test_dataframe(state: JointTestState) -> pl.DataFrame:
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"""Builder functions for resamples-related containers.
|
|
2
|
+
|
|
3
|
+
Provides constructors for ResamplesState and helpers for building
|
|
4
|
+
resamples from inference results. Moved from state.py to keep modules
|
|
5
|
+
under the 800-line limit.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
import numpy as np
|
|
13
|
+
|
|
14
|
+
from bossanova.internal.containers.schemas import (
|
|
15
|
+
Col,
|
|
16
|
+
ResamplesRawSchema,
|
|
17
|
+
)
|
|
18
|
+
from bossanova.internal.containers.structs.state import (
|
|
19
|
+
ResamplesState,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
import polars as pl
|
|
24
|
+
from numpy.typing import NDArray
|
|
25
|
+
|
|
26
|
+
from bossanova.internal.containers.structs.state import (
|
|
27
|
+
InferenceState,
|
|
28
|
+
MeeState,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
__all__ = [
|
|
32
|
+
"build_mee_resamples",
|
|
33
|
+
"build_params_resamples",
|
|
34
|
+
"build_resamples_dataframe",
|
|
35
|
+
"build_resamples_state",
|
|
36
|
+
"extract_mee_names",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def build_resamples_state(
|
|
41
|
+
*,
|
|
42
|
+
samples: NDArray[np.floating],
|
|
43
|
+
observed: NDArray[np.floating],
|
|
44
|
+
names: tuple[str, ...] | list[str],
|
|
45
|
+
method: str,
|
|
46
|
+
n_resamples: int,
|
|
47
|
+
context: str,
|
|
48
|
+
) -> ResamplesState:
|
|
49
|
+
"""Build a ResamplesState from resampling results.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
samples: Resampled statistics array, shape (n_resamples, k).
|
|
53
|
+
observed: Observed statistics, shape (k,).
|
|
54
|
+
names: Term/effect names corresponding to columns of samples.
|
|
55
|
+
method: Resampling method (``"boot"`` or ``"perm"``).
|
|
56
|
+
n_resamples: Number of resamples.
|
|
57
|
+
context: What was resampled (``"params"`` or ``"effects"``).
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
Frozen ResamplesState instance.
|
|
61
|
+
|
|
62
|
+
Examples:
|
|
63
|
+
>>> state = build_resamples_state(
|
|
64
|
+
... samples=np.random.randn(100, 2),
|
|
65
|
+
... observed=np.array([1.0, 2.0]),
|
|
66
|
+
... names=("Intercept", "x"),
|
|
67
|
+
... method="boot",
|
|
68
|
+
... n_resamples=100,
|
|
69
|
+
... context="params",
|
|
70
|
+
... )
|
|
71
|
+
>>> state.method
|
|
72
|
+
'boot'
|
|
73
|
+
"""
|
|
74
|
+
if isinstance(names, list):
|
|
75
|
+
names = tuple(names)
|
|
76
|
+
|
|
77
|
+
return ResamplesState(
|
|
78
|
+
samples=samples,
|
|
79
|
+
observed=observed,
|
|
80
|
+
names=names,
|
|
81
|
+
method=method,
|
|
82
|
+
n_resamples=n_resamples,
|
|
83
|
+
context=context,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def build_resamples_dataframe(rs: ResamplesState) -> pl.DataFrame:
|
|
88
|
+
"""Build a long-format DataFrame of raw resampled values.
|
|
89
|
+
|
|
90
|
+
Returns one row per (resample, term) combination with the raw
|
|
91
|
+
resampled value — coefficient estimates for bootstrap, null
|
|
92
|
+
t-statistics for permutation.
|
|
93
|
+
|
|
94
|
+
Columns: ``resample`` (int), ``term`` (str), ``value`` (float).
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
rs: Frozen ResamplesState from bootstrap or permutation inference.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Polars DataFrame with ``n_resamples × k`` rows, where *k* is the
|
|
101
|
+
number of terms/effects.
|
|
102
|
+
|
|
103
|
+
Examples:
|
|
104
|
+
>>> df = build_resamples_dataframe(rs)
|
|
105
|
+
>>> df.columns
|
|
106
|
+
['resample', 'term', 'value']
|
|
107
|
+
>>> df.shape
|
|
108
|
+
(1000, 3) # 100 resamples × 10 terms
|
|
109
|
+
"""
|
|
110
|
+
import polars as pl
|
|
111
|
+
|
|
112
|
+
samples = np.asarray(rs.samples)
|
|
113
|
+
n_resamples, k = samples.shape
|
|
114
|
+
names = list(rs.names)
|
|
115
|
+
|
|
116
|
+
# Repeat resample indices for each term, repeat term names for each resample
|
|
117
|
+
resample_idx = np.repeat(np.arange(n_resamples), k)
|
|
118
|
+
term_names = names * n_resamples
|
|
119
|
+
values = samples.ravel()
|
|
120
|
+
|
|
121
|
+
return pl.DataFrame(
|
|
122
|
+
{
|
|
123
|
+
Col.RESAMPLE: resample_idx,
|
|
124
|
+
Col.TERM: term_names,
|
|
125
|
+
Col.VALUE: values.tolist(),
|
|
126
|
+
},
|
|
127
|
+
schema=ResamplesRawSchema,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def extract_mee_names(mee: MeeState) -> tuple[str, ...]:
|
|
132
|
+
"""Extract human-readable names from a MeeState.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
mee: The MeeState to extract names from.
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
Tuple of effect names for each estimate.
|
|
139
|
+
"""
|
|
140
|
+
grid = mee.grid
|
|
141
|
+
focal = mee.focal_var
|
|
142
|
+
|
|
143
|
+
if mee.type == "contrasts" and "contrast" in grid.columns:
|
|
144
|
+
return tuple(grid["contrast"].to_list())
|
|
145
|
+
|
|
146
|
+
if focal in grid.columns:
|
|
147
|
+
return tuple(str(v) for v in grid[focal].to_list())
|
|
148
|
+
|
|
149
|
+
# Fallback: numbered estimates
|
|
150
|
+
return tuple(f"estimate_{i}" for i in range(len(mee.estimate)))
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def build_params_resamples(
|
|
154
|
+
inference: InferenceState | None,
|
|
155
|
+
fit_coef: np.ndarray,
|
|
156
|
+
x_names: tuple[str, ...],
|
|
157
|
+
how: str,
|
|
158
|
+
) -> ResamplesState | None:
|
|
159
|
+
"""Build ResamplesState from params inference if samples are available.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
inference: The InferenceState from params inference, or None.
|
|
163
|
+
fit_coef: Coefficient estimates from the FitState.
|
|
164
|
+
x_names: Design matrix column names from the DataBundle.
|
|
165
|
+
how: Inference method used (``"boot"``, ``"perm"``, etc.).
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
ResamplesState if boot/perm samples were saved, else None.
|
|
169
|
+
"""
|
|
170
|
+
if inference is None:
|
|
171
|
+
return None
|
|
172
|
+
|
|
173
|
+
if how == "boot" and inference.boot_samples is not None:
|
|
174
|
+
return build_resamples_state(
|
|
175
|
+
samples=inference.boot_samples,
|
|
176
|
+
observed=fit_coef,
|
|
177
|
+
names=x_names,
|
|
178
|
+
method="boot",
|
|
179
|
+
n_resamples=inference.n_resamples,
|
|
180
|
+
context="params",
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
if how == "perm" and inference.perm_samples is not None:
|
|
184
|
+
return build_resamples_state(
|
|
185
|
+
samples=inference.perm_samples,
|
|
186
|
+
observed=inference.statistic,
|
|
187
|
+
names=x_names,
|
|
188
|
+
method="perm",
|
|
189
|
+
n_resamples=inference.n_resamples,
|
|
190
|
+
context="params",
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
return None
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def build_mee_resamples(
|
|
197
|
+
mee: MeeState | None,
|
|
198
|
+
samples: np.ndarray | None,
|
|
199
|
+
how: str,
|
|
200
|
+
) -> ResamplesState | None:
|
|
201
|
+
"""Build ResamplesState from MEE inference if samples are available.
|
|
202
|
+
|
|
203
|
+
Args:
|
|
204
|
+
mee: The MeeState from explore, or None.
|
|
205
|
+
samples: Raw resample array from dispatch_mee_inference, or None.
|
|
206
|
+
how: Inference method used (``"boot"``, ``"perm"``, etc.).
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
ResamplesState if boot/perm samples were saved, else None.
|
|
210
|
+
"""
|
|
211
|
+
if samples is None or mee is None:
|
|
212
|
+
return None
|
|
213
|
+
|
|
214
|
+
names = extract_mee_names(mee)
|
|
215
|
+
|
|
216
|
+
method = "boot" if how == "boot" else "perm"
|
|
217
|
+
observed = mee.estimate if how == "boot" else mee.statistic
|
|
218
|
+
|
|
219
|
+
return build_resamples_state(
|
|
220
|
+
samples=samples,
|
|
221
|
+
observed=observed,
|
|
222
|
+
names=names,
|
|
223
|
+
method=method,
|
|
224
|
+
n_resamples=samples.shape[0],
|
|
225
|
+
context="effects",
|
|
226
|
+
)
|
{bossanova-0.1.0.dev11 → bossanova-0.1.0.dev12}/bossanova/internal/containers/builders/results.py
RENAMED
|
@@ -17,29 +17,43 @@ __all__ = [
|
|
|
17
17
|
]
|
|
18
18
|
|
|
19
19
|
# Standard inference column names, in canonical display order.
|
|
20
|
+
# Estimation group (se, CIs) first, then testing group (statistic, df, p_value).
|
|
20
21
|
_INFERENCE_COLS: tuple[str, ...] = (
|
|
21
22
|
Col.SE,
|
|
23
|
+
Col.CI_LOWER,
|
|
24
|
+
Col.CI_UPPER,
|
|
22
25
|
Col.STATISTIC,
|
|
23
26
|
Col.DF,
|
|
24
27
|
Col.P_VALUE,
|
|
25
|
-
Col.CI_LOWER,
|
|
26
|
-
Col.CI_UPPER,
|
|
27
28
|
)
|
|
28
29
|
|
|
30
|
+
# Columns excluded per inference method.
|
|
31
|
+
_BOOT_EXCLUDE: frozenset[str] = frozenset({Col.P_VALUE})
|
|
32
|
+
_PERM_EXCLUDE: frozenset[str] = frozenset({Col.CI_LOWER, Col.CI_UPPER})
|
|
29
33
|
|
|
30
|
-
|
|
34
|
+
|
|
35
|
+
def append_inference_columns(
|
|
36
|
+
df: pl.DataFrame,
|
|
37
|
+
state: object,
|
|
38
|
+
method: str | None = None,
|
|
39
|
+
) -> pl.DataFrame:
|
|
31
40
|
"""Append standard inference columns to a DataFrame if available.
|
|
32
41
|
|
|
33
42
|
Checks ``state.has_inference`` and, when True, adds each inference
|
|
34
|
-
column
|
|
35
|
-
|
|
36
|
-
|
|
43
|
+
column that is not None on *state*. Columns are added in canonical
|
|
44
|
+
order: se, ci_lower, ci_upper, statistic, df, p_value.
|
|
45
|
+
|
|
46
|
+
When *method* is ``"boot"``, the ``p_value`` column is excluded.
|
|
47
|
+
When *method* is ``"perm"``, the ``ci_lower`` and ``ci_upper``
|
|
48
|
+
columns are excluded.
|
|
37
49
|
|
|
38
50
|
Args:
|
|
39
51
|
df: Base DataFrame to augment (not mutated).
|
|
40
52
|
state: Object with a ``has_inference`` bool and optional ``se``,
|
|
41
53
|
``statistic``, ``df``, ``p_value``, ``ci_lower``,
|
|
42
54
|
``ci_upper`` array attributes.
|
|
55
|
+
method: Inference method (``"asymp"``, ``"boot"``, ``"perm"``,
|
|
56
|
+
or ``None``). Controls which columns are included.
|
|
43
57
|
|
|
44
58
|
Returns:
|
|
45
59
|
A new DataFrame with inference columns appended (or the
|
|
@@ -48,7 +62,16 @@ def append_inference_columns(df: pl.DataFrame, state: object) -> pl.DataFrame:
|
|
|
48
62
|
if not getattr(state, "has_inference", False):
|
|
49
63
|
return df
|
|
50
64
|
|
|
65
|
+
if method == "boot":
|
|
66
|
+
exclude = _BOOT_EXCLUDE
|
|
67
|
+
elif method == "perm":
|
|
68
|
+
exclude = _PERM_EXCLUDE
|
|
69
|
+
else:
|
|
70
|
+
exclude = frozenset()
|
|
71
|
+
|
|
51
72
|
for col_name in _INFERENCE_COLS:
|
|
73
|
+
if col_name in exclude:
|
|
74
|
+
continue
|
|
52
75
|
values = getattr(state, col_name, None)
|
|
53
76
|
if values is not None:
|
|
54
77
|
df = df.with_columns(pl.Series(col_name, values))
|