bossanova 0.1.0.dev17__tar.gz → 0.1.0.dev19__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.dev17 → bossanova-0.1.0.dev19}/.gitignore +1 -1
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/PKG-INFO +16 -1
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/README.md +15 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/__init__.py +5 -1
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/__init__.py +18 -2
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/expressions.py +13 -13
- bossanova-0.1.0.dev19/bossanova/internal/compare/__init__.py +12 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/compare/compare.py +28 -11
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/compare/cv.py +5 -5
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/compare/deviance.py +1 -1
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/compare/f_test.py +1 -1
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/compare/helpers.py +3 -3
- bossanova-0.1.0.dev19/bossanova/internal/compare/ic.py +160 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/compare/lrt.py +1 -1
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/compare/lrt_compare.py +1 -1
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/compare/refit.py +1 -1
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/builders/dataframes.py +2 -1
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/builders/results.py +1 -2
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/builders/specs.py +13 -4
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/schemas.py +3 -2
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/structs/data.py +1 -1
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/structs/display.py +50 -1
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/structs/explore.py +4 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/structs/specs.py +3 -1
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/structs/state.py +52 -19
- {bossanova-0.1.0.dev17/bossanova/internal/maths → bossanova-0.1.0.dev19/bossanova/internal}/design/__init__.py +26 -31
- {bossanova-0.1.0.dev17/bossanova/internal/maths → bossanova-0.1.0.dev19/bossanova/internal}/design/coding.py +44 -250
- {bossanova-0.1.0.dev17/bossanova/internal/maths → bossanova-0.1.0.dev19/bossanova/internal}/design/reference.py +1 -1
- bossanova-0.1.0.dev19/bossanova/internal/fit/__init__.py +57 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal/fit}/convergence.py +1 -1
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal/fit}/diagnostics.py +29 -5
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/fit/dispatch.py +88 -23
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/fit/glm.py +5 -13
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/fit/glmer.py +13 -20
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/fit/lmer.py +7 -17
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/fit/ols.py +0 -7
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal/fit}/predict.py +6 -6
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/__init__.py +11 -6
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal/formula}/bundle.py +28 -4
- {bossanova-0.1.0.dev17/bossanova/internal/operations/common → bossanova-0.1.0.dev19/bossanova/internal/formula}/contrast_registry.py +11 -1
- bossanova-0.1.0.dev17/bossanova/internal/operations/contrasts.py → bossanova-0.1.0.dev19/bossanova/internal/formula/contrast_specs.py +13 -13
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/design.py +2 -2
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/encoding.py +45 -25
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/evaluate.py +46 -73
- bossanova-0.1.0.dev19/bossanova/internal/formula/evaluate_contrast.py +399 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/evaluate_newdata.py +7 -39
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/evaluate_transforms.py +6 -79
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/helpers.py +1 -34
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/parse.py +4 -4
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/parser/__init__.py +12 -1
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/parser/expr.py +19 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/parser/parser.py +26 -1
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/random_effects.py +143 -135
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/infer/__init__.py +21 -15
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/infer/asymptotic.py +34 -9
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/infer/bootstrap.py +22 -18
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/infer/cv.py +17 -19
- bossanova-0.1.0.dev19/bossanova/internal/infer/dispatch.py +491 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/infer/mee.py +22 -14
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/infer/params.py +31 -43
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/infer/permutation.py +3 -3
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/infer/prediction.py +14 -9
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/infer/profile.py +14 -8
- bossanova-0.1.0.dev19/bossanova/internal/infer/resample/__init__.py +49 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal/infer}/resample/common.py +1 -1
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal/infer}/resample/glmer.py +50 -66
- bossanova-0.1.0.dev19/bossanova/internal/infer/resample/lm_operators.py +151 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal/infer}/resample/lmer.py +15 -24
- bossanova-0.1.0.dev19/bossanova/internal/infer/resample/results.py +136 -0
- bossanova-0.1.0.dev19/bossanova/internal/infer/resample/simulate.py +124 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/infer/satterthwaite_emm.py +3 -3
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/__init__.py +34 -29
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/bracket_contrasts.py +3 -3
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/compute.py +61 -63
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/contrasts.py +105 -261
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/emm.py +4 -4
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/explore.py +2 -2
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/explore_parser.py +25 -2
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/explore_scanner.py +2 -2
- {bossanova-0.1.0.dev17/bossanova/internal/operations/common → bossanova-0.1.0.dev19/bossanova/internal/marginal}/factors.py +4 -4
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/grid.py +3 -3
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/inference.py +2 -2
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/joint_tests.py +3 -3
- bossanova-0.1.0.dev17/bossanova/internal/maths/inference/contrasts.py → bossanova-0.1.0.dev19/bossanova/internal/marginal/matrices.py +114 -111
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/slopes.py +8 -6
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal/marginal}/transforms.py +8 -8
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/__init__.py +22 -42
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/distributions/__init__.py +1 -1
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/inference/__init__.py +0 -18
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/inference/welch.py +12 -9
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/linalg/__init__.py +2 -4
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/linalg/schur.py +3 -3
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/linalg/sparse.py +3 -70
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/solvers/glmer.py +1 -7
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/solvers/lambda_template.py +3 -3
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/solvers/lmer.py +2 -2
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/solvers/pirls_sparse.py +3 -3
- bossanova-0.1.0.dev19/bossanova/internal/rendering/__init__.py +22 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/rendering/latex.py +7 -7
- bossanova-0.1.0.dev19/bossanova/internal/rendering/markdown.py +163 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/simulation/__init__.py +17 -20
- bossanova-0.1.0.dev19/bossanova/internal/simulation/dgp/__init__.py +13 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/simulation/dgp/glm.py +2 -2
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/simulation/dgp/glmer.py +2 -2
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/simulation/dgp/lm.py +2 -2
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/simulation/dgp/lmer.py +2 -2
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/simulation/harness.py +11 -11
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/simulation/metrics.py +3 -23
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/simulation/power.py +149 -8
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/README.md +2 -2
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/__init__.py +25 -3
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/core.py +2 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/core_viz.py +66 -3
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/design.py +50 -71
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/fit_layers.py +19 -36
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/helpers.py +85 -1
- bossanova-0.1.0.dev19/bossanova/internal/viz/mem.py +642 -0
- bossanova-0.1.0.dev19/bossanova/internal/viz/mem_forest.py +538 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/params.py +31 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/predict.py +48 -45
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/profile.py +50 -12
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/resamples.py +13 -13
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/resid.py +3 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/vif.py +6 -13
- bossanova-0.1.0.dev19/bossanova/model/__init__.py +7 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/model/core.py +447 -398
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/model/result.py +84 -0
- bossanova-0.1.0.dev19/bossanova/model/summary.py +1103 -0
- bossanova-0.1.0.dev19/pyproject.toml +246 -0
- bossanova-0.1.0.dev17/bossanova/internal/containers/builders/data.py +0 -10
- bossanova-0.1.0.dev17/bossanova/internal/operations/__init__.py +0 -195
- bossanova-0.1.0.dev17/bossanova/internal/operations/common/__init__.py +0 -33
- bossanova-0.1.0.dev17/bossanova/internal/operations/common/data_utils.py +0 -36
- bossanova-0.1.0.dev17/bossanova/internal/operations/compare/__init__.py +0 -6
- bossanova-0.1.0.dev17/bossanova/internal/operations/fit/__init__.py +0 -31
- bossanova-0.1.0.dev17/bossanova/internal/operations/profile.py +0 -8
- bossanova-0.1.0.dev17/bossanova/internal/operations/rendering/__init__.py +0 -5
- bossanova-0.1.0.dev17/bossanova/internal/operations/resample/__init__.py +0 -75
- bossanova-0.1.0.dev17/bossanova/internal/operations/resample/glm.py +0 -786
- bossanova-0.1.0.dev17/bossanova/internal/operations/resample/lm.py +0 -796
- bossanova-0.1.0.dev17/bossanova/internal/operations/resample/lm_bca.py +0 -326
- bossanova-0.1.0.dev17/bossanova/internal/operations/resample/lm_operators.py +0 -337
- bossanova-0.1.0.dev17/bossanova/internal/operations/resample/mixed.py +0 -14
- bossanova-0.1.0.dev17/bossanova/internal/operations/resample/results.py +0 -299
- bossanova-0.1.0.dev17/bossanova/internal/operations/resample/utils.py +0 -128
- bossanova-0.1.0.dev17/bossanova/internal/operations/simulation/dgp/__init__.py +0 -13
- bossanova-0.1.0.dev17/bossanova/internal/viz/mem.py +0 -478
- bossanova-0.1.0.dev17/bossanova/model/__init__.py +0 -6
- bossanova-0.1.0.dev17/bossanova/model/summary.py +0 -467
- bossanova-0.1.0.dev17/pyproject.toml +0 -580
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/LICENSE +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/README.md +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/advertising.csv +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/cake.csv +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/chickweight.csv +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/credit.csv +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/gammas.csv +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/mtcars.csv +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/penguins.csv +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/poker.csv +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/sleep.csv +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/titanic.csv +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/titanic_test.csv +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/data/titanic_train.csv +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/distributions/__init__.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/distributions/continuous.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/distributions/discrete.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/distributions/varying.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/__init__.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/__init__.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/builders/__init__.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/builders/resamples.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/builders/state.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/structs/__init__.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/structs/formula.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/validators.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/maths → bossanova-0.1.0.dev19/bossanova/internal}/design/names.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/maths → bossanova-0.1.0.dev19/bossanova/internal}/design/z_matrix.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/fit/rank.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal/fit}/varying.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/parser/scanner.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/formula/parser/token.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations/common → bossanova-0.1.0.dev19/bossanova/internal/infer}/formula_utils.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal/infer}/resample/core.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/infer/resample_bundle.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/infer/simulation.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/conditions.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/marginal/validation.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/backend/__init__.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/backend/dispatch.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/backend/jax.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/backend/numpy.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/backend/protocol.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/batching.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/config.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/convergence.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/differentiation.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/distributions/algebra.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/distributions/base.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/distributions/core.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/distributions/derived.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/distributions/factories.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/distributions/plotting.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/distributions/probability.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/family/__init__.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/family/binomial.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/family/create.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/family/gamma.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/family/gaussian.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/family/links.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/family/poisson.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/family/response.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/family/schema.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/family/tdist.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/inference/diagnostics.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/inference/estimation.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/inference/hypothesis.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/inference/information_criteria.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/inference/multiplicity.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/inference/profile.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/inference/sandwich.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/inference/satterthwaite.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/inference/wald_variance.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/linalg/qr.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/linalg/svd.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/predict.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/rng.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/rounding.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/solvers/__init__.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/solvers/glm.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/solvers/heuristics.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/solvers/initialization.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/solvers/lambda_builder.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/solvers/lambda_sparse.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/solvers/optimize.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/solvers/quadrature.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/tolerances.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/transforms.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/variance.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/maths/weights.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/simulation/dgp/generate.py +0 -0
- {bossanova-0.1.0.dev17/bossanova/internal/operations → bossanova-0.1.0.dev19/bossanova/internal}/simulation/model_sim.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/cognition.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/compare.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/core_data.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/core_protocols.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/core_sizing.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/dag.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/fit.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/fit_builders.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/lattice.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/layout.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/ranef.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/viz/relationships.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/model/guards.py +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/py.typed +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/tests/bossanova_benchmarks/bootstrap/data/README.md +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/tests/bossanova_benchmarks/insteval/data/README.md +0 -0
- {bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/tests/bossanova_tests/hypothesis/README.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bossanova
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev19
|
|
4
4
|
Summary: Bridging statistical cultures with some jazz
|
|
5
5
|
Author: Eshin Jolly
|
|
6
6
|
License-Expression: MIT
|
|
@@ -70,4 +70,19 @@ m.explore("Days")
|
|
|
70
70
|
m.effects
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
## Development
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Install dependencies
|
|
77
|
+
pixi install
|
|
78
|
+
|
|
79
|
+
# Install the IPython kernel (required for notebooks)
|
|
80
|
+
pixi run setup-kernel
|
|
81
|
+
|
|
82
|
+
# Run the full lint + type-check chain
|
|
83
|
+
pixi run lint
|
|
84
|
+
|
|
85
|
+
# Run fast unit tests
|
|
86
|
+
pixi run test
|
|
87
|
+
```
|
|
73
88
|
|
|
@@ -42,4 +42,19 @@ m.explore("Days")
|
|
|
42
42
|
m.effects
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
## Development
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Install dependencies
|
|
49
|
+
pixi install
|
|
50
|
+
|
|
51
|
+
# Install the IPython kernel (required for notebooks)
|
|
52
|
+
pixi run setup-kernel
|
|
53
|
+
|
|
54
|
+
# Run the full lint + type-check chain
|
|
55
|
+
pixi run lint
|
|
56
|
+
|
|
57
|
+
# Run fast unit tests
|
|
58
|
+
pixi run test
|
|
59
|
+
```
|
|
45
60
|
|
|
@@ -31,11 +31,14 @@ from bossanova.data import ( # noqa: E402
|
|
|
31
31
|
from bossanova.model import model # noqa: E402
|
|
32
32
|
|
|
33
33
|
# Statistics
|
|
34
|
-
from bossanova.internal.
|
|
34
|
+
from bossanova.internal.compare import compare, lrt # noqa: E402
|
|
35
35
|
|
|
36
36
|
# Visualization
|
|
37
37
|
from bossanova.internal import viz # noqa: E402
|
|
38
38
|
|
|
39
|
+
# Export utilities
|
|
40
|
+
from bossanova.internal.rendering.markdown import to_markdown # noqa: E402
|
|
41
|
+
|
|
39
42
|
# Expressions
|
|
40
43
|
from bossanova import expressions # noqa: E402
|
|
41
44
|
|
|
@@ -53,6 +56,7 @@ __all__ = [
|
|
|
53
56
|
"set_display_digits",
|
|
54
57
|
"set_singular_tolerance",
|
|
55
58
|
"show_datasets",
|
|
59
|
+
"to_markdown",
|
|
56
60
|
"viz",
|
|
57
61
|
]
|
|
58
62
|
|
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
"""Bundled sample datasets for regression and mixed-effects modeling.
|
|
1
|
+
"""Bundled sample datasets for regression and mixed-effects modeling.
|
|
2
|
+
|
|
3
|
+
| Dataset | Argument | Description |
|
|
4
|
+
|---------|----------|-------------|
|
|
5
|
+
| Advertising | `"advertising"` | TV, radio, newspaper ad spend vs sales (200 x 4) |
|
|
6
|
+
| Cake | `"cake"` | Baking angle by recipe and temperature (270 x 5) |
|
|
7
|
+
| ChickWeight | `"chickweight"` | Chick weight over time by diet (578 x 4) |
|
|
8
|
+
| Credit | `"credit"` | Credit card balance by income and demographics (400 x 11) |
|
|
9
|
+
| Gammas | `"gammas"` | Simulated BOLD signal for Gamma GLM (6000 x 4) |
|
|
10
|
+
| mtcars | `"mtcars"` | Motor Trend car road tests (32 x 12) |
|
|
11
|
+
| Penguins | `"penguins"` | Palmer Penguins body measurements (344 x 8) |
|
|
12
|
+
| Poker | `"poker"` | Poker hand outcomes by skill and limit (300 x 4) |
|
|
13
|
+
| Sleep | `"sleep"` | Reaction time vs sleep deprivation (180 x 3) |
|
|
14
|
+
| Titanic | `"titanic"` | Passenger survival with demographics (891 x 15) |
|
|
15
|
+
| Titanic Train | `"titanic_train"` | Titanic training set, Kaggle format (891 x 12) |
|
|
16
|
+
| Titanic Test | `"titanic_test"` | Titanic test set, Kaggle format (418 x 11) |
|
|
17
|
+
"""
|
|
2
18
|
|
|
3
19
|
from importlib.resources import files
|
|
4
20
|
from typing import Literal
|
|
@@ -52,7 +68,7 @@ def show_datasets() -> pl.DataFrame:
|
|
|
52
68
|
```python
|
|
53
69
|
from bossanova.data import show_datasets
|
|
54
70
|
show_datasets()
|
|
55
|
-
# shape: (
|
|
71
|
+
# shape: (12, 2)
|
|
56
72
|
# ┌───────────────┬─────────────────────────────────┐
|
|
57
73
|
# │ name ┆ description │
|
|
58
74
|
# │ --- ┆ --- │
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
This module provides stateless Polars expressions for data transformations
|
|
4
4
|
commonly used in statistical modeling. These match the semantics of the
|
|
5
|
-
formula-based transforms in `bossanova.internal.
|
|
6
|
-
|
|
7
|
-
Core Transforms
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Additional Helpers
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
5
|
+
formula-based transforms in `bossanova.internal.formula`.
|
|
6
|
+
|
|
7
|
+
**Core Transforms:**
|
|
8
|
+
- `center(col)` — subtract mean only
|
|
9
|
+
- `norm(col)` — divide by std only
|
|
10
|
+
- `zscore(col)` — traditional z-score (1 SD)
|
|
11
|
+
- `scale(col)` — Gelman scaling (2 SD)
|
|
12
|
+
|
|
13
|
+
**Additional Helpers:**
|
|
14
|
+
- `rank(col, method)` — average-method rank transform
|
|
15
|
+
- `winsorize(col, lower, upper)` — percentile capping
|
|
16
|
+
- `lag(col, n)` — lagged values
|
|
17
|
+
- `lead(col, n)` — lead values
|
|
18
18
|
|
|
19
19
|
The scale() transform follows Gelman (2008) recommendation to divide by
|
|
20
20
|
2 standard deviations, making continuous predictor coefficients directly
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Model comparison: information criteria, likelihood ratio tests, and composite tables.
|
|
2
|
+
|
|
3
|
+
Call chain:
|
|
4
|
+
bossanova.compare(m1, m2, ...) -> compare() (composite AIC/BIC/loglik table)
|
|
5
|
+
bossanova.lrt(m1, m2) -> lrt() (nested model likelihood ratio test)
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from bossanova.internal.compare.compare import compare
|
|
9
|
+
from bossanova.internal.compare.ic import compare_aic, compare_bic
|
|
10
|
+
from bossanova.internal.compare.lrt import lrt
|
|
11
|
+
|
|
12
|
+
__all__ = ["compare", "compare_aic", "compare_bic", "lrt"]
|
|
@@ -35,16 +35,17 @@ import polars as pl
|
|
|
35
35
|
|
|
36
36
|
from bossanova.internal.maths.config import get_display_digits
|
|
37
37
|
from bossanova.internal.maths.rounding import round_float_columns
|
|
38
|
-
from bossanova.internal.
|
|
39
|
-
from bossanova.internal.
|
|
40
|
-
from bossanova.internal.
|
|
41
|
-
from bossanova.internal.
|
|
42
|
-
|
|
38
|
+
from bossanova.internal.compare.cv import compare_cv
|
|
39
|
+
from bossanova.internal.compare.deviance import compare_deviance
|
|
40
|
+
from bossanova.internal.compare.f_test import compare_f_test
|
|
41
|
+
from bossanova.internal.compare.helpers import (
|
|
42
|
+
resolve_method,
|
|
43
43
|
sort_models_by_complexity,
|
|
44
44
|
validate_models,
|
|
45
45
|
)
|
|
46
|
-
from bossanova.internal.
|
|
47
|
-
from bossanova.internal.
|
|
46
|
+
from bossanova.internal.compare.ic import compare_aic, compare_bic
|
|
47
|
+
from bossanova.internal.compare.lrt_compare import compare_lrt
|
|
48
|
+
from bossanova.internal.compare.refit import refit_with_ml
|
|
48
49
|
|
|
49
50
|
__all__ = ["compare"]
|
|
50
51
|
|
|
@@ -78,6 +79,8 @@ def compare(
|
|
|
78
79
|
- "lrt": Likelihood ratio test (for mixed models)
|
|
79
80
|
- "deviance": Deviance test (for glm)
|
|
80
81
|
- "cv": Cross-validation comparison (for lm/glm)
|
|
82
|
+
- "aic": AIC comparison with delta-AIC and Akaike weights
|
|
83
|
+
- "bic": BIC comparison with delta-BIC and Schwarz weights
|
|
81
84
|
sort: If True, sort models by complexity before comparing.
|
|
82
85
|
This ensures proper nesting order.
|
|
83
86
|
refit: If True and models are lmer/glmer with REML estimation,
|
|
@@ -140,6 +143,15 @@ def compare(
|
|
|
140
143
|
- diff_se: Nadeau-Bengio corrected standard error
|
|
141
144
|
- p_value: Two-sided p-value
|
|
142
145
|
|
|
146
|
+
For AIC/BIC comparison:
|
|
147
|
+
- model: Formula string
|
|
148
|
+
- npar: Number of estimated parameters
|
|
149
|
+
- loglik: Log-likelihood
|
|
150
|
+
- deviance: Deviance (-2 * loglik)
|
|
151
|
+
- AIC/BIC: Information criteria
|
|
152
|
+
- delta_AIC/delta_BIC: Difference from best model
|
|
153
|
+
- weight: Akaike/Schwarz weight (model probability)
|
|
154
|
+
|
|
143
155
|
Raises:
|
|
144
156
|
ValueError: If models are not valid for comparison.
|
|
145
157
|
|
|
@@ -211,15 +223,15 @@ def compare(
|
|
|
211
223
|
# Validate and auto-fit models (pass method and refit for REML check)
|
|
212
224
|
models = validate_models(models, method=method, refit=refit)
|
|
213
225
|
|
|
214
|
-
# Sort if requested (not applicable for CV)
|
|
215
|
-
if sort and method
|
|
226
|
+
# Sort if requested (not applicable for CV or IC methods which sort internally)
|
|
227
|
+
if sort and method not in ("cv", "aic", "bic"):
|
|
216
228
|
model_list = sort_models_by_complexity(models)
|
|
217
229
|
else:
|
|
218
230
|
model_list = list(models)
|
|
219
231
|
|
|
220
232
|
# Infer method if auto
|
|
221
233
|
if method == "auto":
|
|
222
|
-
method =
|
|
234
|
+
method = resolve_method(model_list[0])
|
|
223
235
|
|
|
224
236
|
# For LRT with refit=True, refit REML models with ML
|
|
225
237
|
if method == "lrt" and refit:
|
|
@@ -234,9 +246,14 @@ def compare(
|
|
|
234
246
|
result = compare_deviance(model_list, test=test)
|
|
235
247
|
elif method == "cv":
|
|
236
248
|
result = compare_cv(model_list, cv=cv, seed=seed, metric=metric)
|
|
249
|
+
elif method == "aic":
|
|
250
|
+
result = compare_aic(model_list)
|
|
251
|
+
elif method == "bic":
|
|
252
|
+
result = compare_bic(model_list)
|
|
237
253
|
else:
|
|
238
254
|
raise ValueError(
|
|
239
|
-
f"Unknown method: {method}.
|
|
255
|
+
f"Unknown method: {method}. "
|
|
256
|
+
"Use 'auto', 'f', 'lrt', 'deviance', 'cv', 'aic', or 'bic'."
|
|
240
257
|
)
|
|
241
258
|
|
|
242
259
|
# Round float columns to significant figures (digits=0 disables rounding)
|
|
@@ -13,19 +13,19 @@ from scipy import stats
|
|
|
13
13
|
|
|
14
14
|
from bossanova.internal.containers.schemas import Col, ComparisonCv
|
|
15
15
|
from bossanova.internal.maths.rng import RNG
|
|
16
|
-
from bossanova.internal.
|
|
17
|
-
from bossanova.internal.
|
|
16
|
+
from bossanova.internal.compare.helpers import get_model_type
|
|
17
|
+
from bossanova.internal.infer.resample.core import (
|
|
18
18
|
generate_kfold_indices,
|
|
19
19
|
generate_loo_indices,
|
|
20
20
|
)
|
|
21
21
|
|
|
22
22
|
__all__ = [
|
|
23
23
|
"compare_cv",
|
|
24
|
-
"
|
|
24
|
+
"compute_cv_fold_score",
|
|
25
25
|
]
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
def
|
|
28
|
+
def compute_cv_fold_score(
|
|
29
29
|
model: Any,
|
|
30
30
|
train_idx: np.ndarray,
|
|
31
31
|
test_idx: np.ndarray,
|
|
@@ -142,7 +142,7 @@ def compare_cv(
|
|
|
142
142
|
|
|
143
143
|
for train_idx, test_idx in splits:
|
|
144
144
|
for i, model in enumerate(models):
|
|
145
|
-
score =
|
|
145
|
+
score = compute_cv_fold_score(model, train_idx, test_idx, metric)
|
|
146
146
|
fold_scores[i].append(score)
|
|
147
147
|
|
|
148
148
|
# Convert to arrays
|
|
@@ -14,7 +14,7 @@ from bossanova.internal.containers.schemas import (
|
|
|
14
14
|
ComparisonDevianceChi2,
|
|
15
15
|
ComparisonDevianceF,
|
|
16
16
|
)
|
|
17
|
-
from bossanova.internal.
|
|
17
|
+
from bossanova.internal.compare.helpers import check_nested
|
|
18
18
|
|
|
19
19
|
__all__ = [
|
|
20
20
|
"compare_deviance",
|
|
@@ -10,7 +10,7 @@ import polars as pl
|
|
|
10
10
|
from scipy import stats
|
|
11
11
|
|
|
12
12
|
from bossanova.internal.containers.schemas import Col, ComparisonFTest
|
|
13
|
-
from bossanova.internal.
|
|
13
|
+
from bossanova.internal.compare.helpers import check_nested
|
|
14
14
|
|
|
15
15
|
__all__ = [
|
|
16
16
|
"compare_f_test",
|
|
@@ -15,7 +15,7 @@ if TYPE_CHECKING:
|
|
|
15
15
|
__all__ = [
|
|
16
16
|
"check_nested",
|
|
17
17
|
"get_model_type",
|
|
18
|
-
"
|
|
18
|
+
"resolve_method",
|
|
19
19
|
"sort_models_by_complexity",
|
|
20
20
|
"validate_models",
|
|
21
21
|
]
|
|
@@ -100,7 +100,7 @@ def validate_models(
|
|
|
100
100
|
|
|
101
101
|
# For LRT, check that all models use ML estimation (unless refit=True)
|
|
102
102
|
model_type = model_types[0]
|
|
103
|
-
inferred_method = method if method != "auto" else
|
|
103
|
+
inferred_method = method if method != "auto" else resolve_method(models[0])
|
|
104
104
|
|
|
105
105
|
if inferred_method == "lrt" and model_type in ("lmer", "glmer") and not refit:
|
|
106
106
|
methods = [m._spec.method for m in models]
|
|
@@ -151,7 +151,7 @@ def sort_models_by_complexity(models: tuple[Any, ...]) -> list[Any]:
|
|
|
151
151
|
return sorted(models, key=get_total_params)
|
|
152
152
|
|
|
153
153
|
|
|
154
|
-
def
|
|
154
|
+
def resolve_method(model: Any) -> str:
|
|
155
155
|
"""Infer the appropriate comparison method for a model type.
|
|
156
156
|
|
|
157
157
|
Uses :func:`classify_model_type` to canonically determine the model type
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""Information criterion comparison for model selection.
|
|
2
|
+
|
|
3
|
+
Computes AIC/BIC tables with delta-IC and Akaike/Schwarz weights,
|
|
4
|
+
following Burnham & Anderson (2002). Unlike hypothesis-test comparisons
|
|
5
|
+
(F-test, LRT, deviance), IC comparison does not require model nesting —
|
|
6
|
+
any set of models fitted to the same data can be compared.
|
|
7
|
+
|
|
8
|
+
Functions:
|
|
9
|
+
compare_aic: Rank models by AIC with delta-AIC and Akaike weights.
|
|
10
|
+
compare_bic: Rank models by BIC with delta-BIC and Schwarz weights.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import math
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
import polars as pl
|
|
19
|
+
|
|
20
|
+
from bossanova.internal.containers.schemas import (
|
|
21
|
+
Col,
|
|
22
|
+
ComparisonAic,
|
|
23
|
+
ComparisonBic,
|
|
24
|
+
)
|
|
25
|
+
from bossanova.internal.maths.family import ESTIMATED_DISPERSION_FAMILIES
|
|
26
|
+
from bossanova.internal.maths.inference import compute_aic, compute_bic
|
|
27
|
+
|
|
28
|
+
__all__ = ["compare_aic", "compare_bic"]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _get_n_params_ic(model: Any) -> int:
|
|
32
|
+
"""Get total number of estimated parameters for IC computation.
|
|
33
|
+
|
|
34
|
+
Follows the same counting as ``compute_diagnostics()``:
|
|
35
|
+
|
|
36
|
+
- ``rank`` (estimable fixed effects)
|
|
37
|
+
- ``+ len(theta)`` for mixed models (variance parameters)
|
|
38
|
+
- ``+ 1`` for families with estimated dispersion (e.g. Gaussian sigma)
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
model: A fitted model instance.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Total parameter count for AIC/BIC computation.
|
|
45
|
+
"""
|
|
46
|
+
k: int = model._bundle.rank
|
|
47
|
+
if model._fit.theta is not None:
|
|
48
|
+
k += len(model._fit.theta)
|
|
49
|
+
if model._spec.family in ESTIMATED_DISPERSION_FAMILIES:
|
|
50
|
+
k += 1
|
|
51
|
+
return k
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def compare_aic(models: list[Any]) -> pl.DataFrame:
|
|
55
|
+
"""Compare models by AIC with delta-AIC and Akaike weights.
|
|
56
|
+
|
|
57
|
+
Models are sorted by AIC (best first). Delta-AIC is the difference
|
|
58
|
+
from the best model. Akaike weights represent the relative likelihood
|
|
59
|
+
of each model being the best, following Burnham & Anderson (2002):
|
|
60
|
+
|
|
61
|
+
w_i = exp(-0.5 * delta_i) / sum(exp(-0.5 * delta_j))
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
models: List of fitted model objects (at least 2).
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
DataFrame with columns: model, npar, loglik, deviance, AIC, BIC,
|
|
68
|
+
delta_AIC, weight. Sorted by AIC ascending (best model first).
|
|
69
|
+
"""
|
|
70
|
+
return _compare_ic(models, criterion="aic")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def compare_bic(models: list[Any]) -> pl.DataFrame:
|
|
74
|
+
"""Compare models by BIC with delta-BIC and Schwarz weights.
|
|
75
|
+
|
|
76
|
+
Models are sorted by BIC (best first). Delta-BIC is the difference
|
|
77
|
+
from the best model. Schwarz weights use the same formula as Akaike
|
|
78
|
+
weights but applied to BIC differences.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
models: List of fitted model objects (at least 2).
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
DataFrame with columns: model, npar, loglik, deviance, AIC, BIC,
|
|
85
|
+
delta_BIC, weight. Sorted by BIC ascending (best model first).
|
|
86
|
+
"""
|
|
87
|
+
return _compare_ic(models, criterion="bic")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _compare_ic(models: list[Any], *, criterion: str) -> pl.DataFrame:
|
|
91
|
+
"""Shared implementation for AIC/BIC comparison.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
models: List of fitted models.
|
|
95
|
+
criterion: ``"aic"`` or ``"bic"``.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
DataFrame sorted by the chosen criterion with delta-IC and weights.
|
|
99
|
+
"""
|
|
100
|
+
formulas: list[str] = []
|
|
101
|
+
npars: list[int] = []
|
|
102
|
+
logliks: list[float] = []
|
|
103
|
+
deviances: list[float] = []
|
|
104
|
+
aics: list[float] = []
|
|
105
|
+
bics: list[float] = []
|
|
106
|
+
|
|
107
|
+
for m in models:
|
|
108
|
+
k = _get_n_params_ic(m)
|
|
109
|
+
loglik = float(m._fit.loglik)
|
|
110
|
+
n = m._bundle.n
|
|
111
|
+
|
|
112
|
+
formulas.append(m.formula)
|
|
113
|
+
npars.append(k)
|
|
114
|
+
logliks.append(loglik)
|
|
115
|
+
deviances.append(-2.0 * loglik)
|
|
116
|
+
aics.append(compute_aic(loglik, k))
|
|
117
|
+
bics.append(compute_bic(loglik, k, n))
|
|
118
|
+
|
|
119
|
+
# Select criterion and schema
|
|
120
|
+
if criterion == "aic":
|
|
121
|
+
ic_values = aics
|
|
122
|
+
delta_col = Col.DELTA_AIC
|
|
123
|
+
schema = ComparisonAic
|
|
124
|
+
else:
|
|
125
|
+
ic_values = bics
|
|
126
|
+
delta_col = Col.DELTA_BIC
|
|
127
|
+
schema = ComparisonBic
|
|
128
|
+
|
|
129
|
+
# Sort all lists by IC value (ascending = best first)
|
|
130
|
+
order = sorted(range(len(models)), key=lambda i: ic_values[i])
|
|
131
|
+
formulas = [formulas[i] for i in order]
|
|
132
|
+
npars = [npars[i] for i in order]
|
|
133
|
+
logliks = [logliks[i] for i in order]
|
|
134
|
+
deviances = [deviances[i] for i in order]
|
|
135
|
+
aics = [aics[i] for i in order]
|
|
136
|
+
bics = [bics[i] for i in order]
|
|
137
|
+
ic_values = [ic_values[i] for i in order]
|
|
138
|
+
|
|
139
|
+
# Delta-IC: difference from best model
|
|
140
|
+
ic_min = ic_values[0]
|
|
141
|
+
deltas = [v - ic_min for v in ic_values]
|
|
142
|
+
|
|
143
|
+
# Akaike/Schwarz weights: exp(-0.5 * delta) / sum(exp(-0.5 * delta))
|
|
144
|
+
raw_weights = [math.exp(-0.5 * d) for d in deltas]
|
|
145
|
+
weight_sum = sum(raw_weights)
|
|
146
|
+
weights = [w / weight_sum for w in raw_weights]
|
|
147
|
+
|
|
148
|
+
return pl.DataFrame(
|
|
149
|
+
{
|
|
150
|
+
Col.MODEL: formulas,
|
|
151
|
+
Col.NPAR: npars,
|
|
152
|
+
Col.LOGLIK: logliks,
|
|
153
|
+
Col.DEVIANCE: deviances,
|
|
154
|
+
Col.AIC_R: aics,
|
|
155
|
+
Col.BIC_R: bics,
|
|
156
|
+
delta_col: deltas,
|
|
157
|
+
Col.WEIGHT: weights,
|
|
158
|
+
},
|
|
159
|
+
schema=schema,
|
|
160
|
+
)
|
|
@@ -16,7 +16,7 @@ from bossanova.internal.containers.schemas import (
|
|
|
16
16
|
from bossanova.internal.maths.config import is_singular
|
|
17
17
|
from bossanova.internal.maths.inference import compute_aic as compute_aic
|
|
18
18
|
from bossanova.internal.maths.inference import compute_bic as _compute_bic
|
|
19
|
-
from bossanova.internal.
|
|
19
|
+
from bossanova.internal.compare.helpers import check_nested, get_model_type
|
|
20
20
|
|
|
21
21
|
__all__ = [
|
|
22
22
|
"compare_lrt",
|
|
@@ -6,7 +6,7 @@ estimation when the original uses REML, enabling valid likelihood ratio tests.
|
|
|
6
6
|
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
|
-
from bossanova.internal.
|
|
9
|
+
from bossanova.internal.compare.helpers import get_model_type
|
|
10
10
|
|
|
11
11
|
__all__ = [
|
|
12
12
|
"refit_with_ml",
|
{bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/builders/dataframes.py
RENAMED
|
@@ -61,7 +61,7 @@ def build_params_dataframe(
|
|
|
61
61
|
Column set varies by inference method:
|
|
62
62
|
|
|
63
63
|
- **asymp**: all inference columns (p_value last).
|
|
64
|
-
- **boot**:
|
|
64
|
+
- **boot**: all inference columns; df = n_resamples.
|
|
65
65
|
- **perm**: no CIs; df = n_valid_resamples.
|
|
66
66
|
- **cv**: PRE columns only.
|
|
67
67
|
- **None**: term + estimate only.
|
|
@@ -96,6 +96,7 @@ def build_params_dataframe(
|
|
|
96
96
|
data[Col.CI_UPPER] = params_inference.ci_upper.tolist()
|
|
97
97
|
data[Col.STATISTIC] = params_inference.statistic.tolist()
|
|
98
98
|
data[Col.DF] = params_inference.df.tolist()
|
|
99
|
+
data[Col.P_VALUE] = params_inference.p_value.tolist()
|
|
99
100
|
return pl.DataFrame(data, schema=ParamsBoot)
|
|
100
101
|
|
|
101
102
|
if method == "perm":
|
{bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/builders/results.py
RENAMED
|
@@ -28,7 +28,7 @@ _INFERENCE_COLS: tuple[str, ...] = (
|
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
# Columns excluded per inference method.
|
|
31
|
-
_BOOT_EXCLUDE: frozenset[str] = frozenset(
|
|
31
|
+
_BOOT_EXCLUDE: frozenset[str] = frozenset()
|
|
32
32
|
_PERM_EXCLUDE: frozenset[str] = frozenset({Col.CI_LOWER, Col.CI_UPPER})
|
|
33
33
|
|
|
34
34
|
|
|
@@ -43,7 +43,6 @@ def append_inference_columns(
|
|
|
43
43
|
column that is not None on *state*. Columns are added in canonical
|
|
44
44
|
order: se, ci_lower, ci_upper, statistic, df, p_value.
|
|
45
45
|
|
|
46
|
-
When *method* is ``"boot"``, the ``p_value`` column is excluded.
|
|
47
46
|
When *method* is ``"perm"``, the ``ci_lower`` and ``ci_upper``
|
|
48
47
|
columns are excluded.
|
|
49
48
|
|
{bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/builders/specs.py
RENAMED
|
@@ -173,7 +173,7 @@ def build_model_spec_from_formula(
|
|
|
173
173
|
if "~" not in formula:
|
|
174
174
|
raise ValueError(f"Invalid formula: {formula!r}. Formula must contain '~'.")
|
|
175
175
|
|
|
176
|
-
from bossanova.internal.
|
|
176
|
+
from bossanova.internal.formula.parse import extract_formula_structure
|
|
177
177
|
|
|
178
178
|
try:
|
|
179
179
|
structure = extract_formula_structure(formula)
|
|
@@ -269,13 +269,20 @@ def build_simulation_spec(
|
|
|
269
269
|
# =============================================================================
|
|
270
270
|
|
|
271
271
|
|
|
272
|
+
_CONTRAST_FUNC_RE = (
|
|
273
|
+
r"(?:treatment|dummy|sum|deviation|helmert|sequential|poly)\((\w+)(?:,\s*[^)]+)?\)"
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
|
|
272
277
|
def parse_formula_simple(formula: str) -> dict[str, Any]:
|
|
273
278
|
"""Simple formula parser for simulation defaults.
|
|
274
279
|
|
|
275
280
|
Parses a model formula to extract variable types for default distributions.
|
|
281
|
+
Recognizes contrast encoding functions (``treatment(x)``, ``sum(x)``, etc.)
|
|
282
|
+
as categorical markers.
|
|
276
283
|
|
|
277
284
|
Args:
|
|
278
|
-
formula: Model formula (e.g., "y ~ x +
|
|
285
|
+
formula: Model formula (e.g., ``"y ~ x + treatment(group) + (1|subject)"``).
|
|
279
286
|
|
|
280
287
|
Returns:
|
|
281
288
|
Dictionary with keys: response, continuous, factors, re_groups.
|
|
@@ -283,6 +290,8 @@ def parse_formula_simple(formula: str) -> dict[str, Any]:
|
|
|
283
290
|
Examples:
|
|
284
291
|
>>> parse_formula_simple("y ~ x + z")
|
|
285
292
|
{'response': 'y', 'continuous': ['x', 'z'], 'factors': [], 're_groups': []}
|
|
293
|
+
>>> parse_formula_simple("y ~ treatment(group) + x")
|
|
294
|
+
{'response': 'y', 'continuous': ['x'], 'factors': ['group'], 're_groups': []}
|
|
286
295
|
"""
|
|
287
296
|
if "~" not in formula:
|
|
288
297
|
msg = f"Invalid formula: missing '~'. Got: {formula}"
|
|
@@ -297,10 +306,10 @@ def parse_formula_simple(formula: str) -> dict[str, Any]:
|
|
|
297
306
|
msg = f"Invalid formula: empty response variable. Got: {formula}"
|
|
298
307
|
raise ValueError(msg)
|
|
299
308
|
|
|
300
|
-
factors = re.findall(
|
|
309
|
+
factors = re.findall(_CONTRAST_FUNC_RE, rhs)
|
|
301
310
|
re_groups = re.findall(r"\([^)]+\|(\w+)\)", rhs)
|
|
302
311
|
|
|
303
|
-
cleaned = re.sub(
|
|
312
|
+
cleaned = re.sub(_CONTRAST_FUNC_RE, "", rhs)
|
|
304
313
|
cleaned = re.sub(r"\([^)]+\|\w+\)", "", cleaned)
|
|
305
314
|
|
|
306
315
|
all_terms = re.findall(r"\b([a-zA-Z_]\w*)\b", cleaned)
|
|
@@ -231,6 +231,7 @@ ParamsBoot = Schema(
|
|
|
231
231
|
Col.CI_UPPER: Float64,
|
|
232
232
|
Col.STATISTIC: Float64,
|
|
233
233
|
Col.DF: Float64,
|
|
234
|
+
Col.P_VALUE: Float64,
|
|
234
235
|
}
|
|
235
236
|
)
|
|
236
237
|
|
|
@@ -528,7 +529,7 @@ VaryingCorrSchema = Schema(
|
|
|
528
529
|
# compare() Schemas (rows = models)
|
|
529
530
|
# =============================================================================
|
|
530
531
|
|
|
531
|
-
#
|
|
532
|
+
# AIC-based model comparison (used by compare(method='aic')).
|
|
532
533
|
ComparisonAic = Schema(
|
|
533
534
|
{
|
|
534
535
|
Col.MODEL: String,
|
|
@@ -542,7 +543,7 @@ ComparisonAic = Schema(
|
|
|
542
543
|
}
|
|
543
544
|
)
|
|
544
545
|
|
|
545
|
-
#
|
|
546
|
+
# BIC-based model comparison (used by compare(method='bic')).
|
|
546
547
|
ComparisonBic = Schema(
|
|
547
548
|
{
|
|
548
549
|
Col.MODEL: String,
|
{bossanova-0.1.0.dev17 → bossanova-0.1.0.dev19}/bossanova/internal/containers/structs/data.py
RENAMED
|
@@ -171,7 +171,7 @@ class DataBundle:
|
|
|
171
171
|
X: NDArray[np.floating] = field(validator=is_ndarray)
|
|
172
172
|
y: NDArray[np.floating] = field(validator=is_ndarray)
|
|
173
173
|
X_names: tuple[str, ...] = field(converter=to_tuple)
|
|
174
|
-
y_name: str
|
|
174
|
+
y_name: str = field(validator=validators.instance_of(str))
|
|
175
175
|
|
|
176
176
|
valid_mask: NDArray[np.bool_] = field(validator=is_ndarray)
|
|
177
177
|
n_total: int = field(validator=validators.instance_of(int))
|