BayesProp 0.1.0.1__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.
- bayesprop-0.1.0.1/PKG-INFO +134 -0
- bayesprop-0.1.0.1/README.md +115 -0
- bayesprop-0.1.0.1/pyproject.toml +166 -0
- bayesprop-0.1.0.1/setup.cfg +4 -0
- bayesprop-0.1.0.1/src/BayesProp.egg-info/PKG-INFO +134 -0
- bayesprop-0.1.0.1/src/BayesProp.egg-info/SOURCES.txt +25 -0
- bayesprop-0.1.0.1/src/BayesProp.egg-info/dependency_links.txt +1 -0
- bayesprop-0.1.0.1/src/BayesProp.egg-info/requires.txt +6 -0
- bayesprop-0.1.0.1/src/BayesProp.egg-info/top_level.txt +1 -0
- bayesprop-0.1.0.1/src/bayesprop/config/__init__.py +0 -0
- bayesprop-0.1.0.1/src/bayesprop/config/global_config.py +27 -0
- bayesprop-0.1.0.1/src/bayesprop/resources/__init__.py +0 -0
- bayesprop-0.1.0.1/src/bayesprop/resources/bayes_nonpaired.py +992 -0
- bayesprop-0.1.0.1/src/bayesprop/resources/bayes_paired_laplace.py +1025 -0
- bayesprop-0.1.0.1/src/bayesprop/resources/bayes_paired_pg.py +1093 -0
- bayesprop-0.1.0.1/src/bayesprop/resources/data_schemas.py +318 -0
- bayesprop-0.1.0.1/src/bayesprop/services/__init__.py +0 -0
- bayesprop-0.1.0.1/src/bayesprop/services/blueprint_file.py +29 -0
- bayesprop-0.1.0.1/src/bayesprop/services/file.py +246 -0
- bayesprop-0.1.0.1/src/bayesprop/utils/__init__.py +0 -0
- bayesprop-0.1.0.1/src/bayesprop/utils/utils.py +619 -0
- bayesprop-0.1.0.1/tests/test_bayes_nonpaired.py +484 -0
- bayesprop-0.1.0.1/tests/test_bayes_paired_laplace.py +395 -0
- bayesprop-0.1.0.1/tests/test_bayes_paired_pg.py +436 -0
- bayesprop-0.1.0.1/tests/test_bfda_utils.py +190 -0
- bayesprop-0.1.0.1/tests/test_data_schemas.py +365 -0
- bayesprop-0.1.0.1/tests/test_file_services.py +168 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: BayesProp
|
|
3
|
+
Version: 0.1.0.1
|
|
4
|
+
Summary: Bayesian A/B testing for proportions
|
|
5
|
+
Author-email: Alexander Vosseler <avosseler@nemetschek.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/AVoss84/bayesProp
|
|
7
|
+
Project-URL: Documentation, https://avoss84.github.io/bayesProp/
|
|
8
|
+
Project-URL: Repository, https://github.com/AVoss84/bayesProp
|
|
9
|
+
Project-URL: Issues, https://github.com/AVoss84/bayesProp/issues
|
|
10
|
+
Keywords: Bayesian inference,A/B testing,Proportions
|
|
11
|
+
Requires-Python: >=3.13
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: matplotlib>=3.10.9
|
|
14
|
+
Requires-Dist: numpy>=2.4.4
|
|
15
|
+
Requires-Dist: pandas>=3.0.2
|
|
16
|
+
Requires-Dist: polyagamma>=2.0.2
|
|
17
|
+
Requires-Dist: pydantic>=2.13.3
|
|
18
|
+
Requires-Dist: scipy>=1.17.1
|
|
19
|
+
|
|
20
|
+
# Bayesian A/B Testing for Proportions
|
|
21
|
+
|
|
22
|
+
[](https://test.pypi.org/project/BayesProp/)
|
|
23
|
+
[](https://avoss84.github.io/bayesProp/)
|
|
24
|
+
[](https://www.python.org/)
|
|
25
|
+
[](https://github.com/AVoss84/bayesProp/actions/workflows/tests.yml)
|
|
26
|
+
[](https://github.com/AVoss84/bayesProp/actions/workflows/tests.yml)
|
|
27
|
+
|
|
28
|
+
A Python package for **Bayesian hypothesis testing** of binary (pass/fail) outcomes in A/B experiments.
|
|
29
|
+
It provides three complementary models, Savage–Dickey Bayes factors, posterior predictive checks,
|
|
30
|
+
Bayes Factor Design Analysis (BFDA) for sample-size planning, and publication-ready plots.
|
|
31
|
+
Please check out our [Getting Started](https://avoss84.github.io/bayesProp/getting_started/) guide for installation and quick examples.
|
|
32
|
+
|
|
33
|
+
## Models
|
|
34
|
+
|
|
35
|
+
| Model | Class | Method | When to use |
|
|
36
|
+
|---|---|---|---|
|
|
37
|
+
| **Non-paired Beta–Bernoulli** | `NonPairedBayesPropTest` | Conjugate Beta posterior | Independent groups, exact & fast |
|
|
38
|
+
| **Paired Logistic (Laplace)** | `PairedBayesPropTest` | MAP + Laplace approximation | Paired scores, large *n*, fast iteration |
|
|
39
|
+
| **Paired Logistic (Pólya–Gamma)** | `PairedBayesPropTestPG` | Exact Gibbs sampling | Paired scores, small *n*, exact posterior |
|
|
40
|
+
|
|
41
|
+
## Quick start
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from bayesprop.resources.bayes_paired_pg import PairedBayesPropTestPG
|
|
45
|
+
from bayesprop.utils.utils import simulate_paired_scores
|
|
46
|
+
|
|
47
|
+
# Simulate paired binary data
|
|
48
|
+
sim = simulate_paired_scores(N=200, delta_A=0.5, seed=42)
|
|
49
|
+
y_A, y_B = sim.y_A, sim.y_B
|
|
50
|
+
|
|
51
|
+
# Fit & summarise
|
|
52
|
+
model = PairedBayesPropTestPG(seed=42, n_iter=2000, burn_in=500, n_chains=4).fit(y_A, y_B)
|
|
53
|
+
print(model.summary) # PairedSummary with mean_delta, ci_95, P(A>B), …
|
|
54
|
+
|
|
55
|
+
# Hypothesis test
|
|
56
|
+
bf = model.savage_dickey_test() # SavageDickeyResult with BF_10, decision, …
|
|
57
|
+
|
|
58
|
+
# Plots
|
|
59
|
+
model.plot_posteriors()
|
|
60
|
+
model.plot_ppc(seed=42)
|
|
61
|
+
model.plot_savage_dickey()
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Package structure
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
├── pyproject.toml
|
|
68
|
+
├── justfile # task runner (just <recipe>)
|
|
69
|
+
├── .pre-commit-config.yaml # ruff format + lint hooks
|
|
70
|
+
├── data/ # evaluation datasets
|
|
71
|
+
├── docs/ # model derivations & MkDocs site
|
|
72
|
+
├── src
|
|
73
|
+
│ ├── bayesprop
|
|
74
|
+
│ │ ├── config/ # global_config, YAML configs
|
|
75
|
+
│ │ ├── resources/
|
|
76
|
+
│ │ │ ├── bayes_nonpaired.py # NonPairedBayesPropTest
|
|
77
|
+
│ │ │ ├── bayes_paired_laplace.py # PairedBayesPropTest
|
|
78
|
+
│ │ │ ├── bayes_paired_pg.py # PairedBayesPropTestPG
|
|
79
|
+
│ │ │ ├── bfda_utils.py # BFDA helpers
|
|
80
|
+
│ │ │ └── data_schemas.py # Pydantic models
|
|
81
|
+
│ │ ├── services/
|
|
82
|
+
│ │ │ └── file.py # CSV / JSON / YAML / XLSX I/O
|
|
83
|
+
│ │ └── utils/
|
|
84
|
+
│ │ └── utils.py # simulate, BFDA power curves, plots
|
|
85
|
+
│ └── notebooks/
|
|
86
|
+
│ ├── bayesian_AB_model_comparison_nonpaired.ipynb
|
|
87
|
+
│ ├── bayesian_AB_model_comparison_paired_laplace.ipynb
|
|
88
|
+
│ └── bayesian_AB_model_comparison_paired_gibbs.ipynb
|
|
89
|
+
└── tests/
|
|
90
|
+
├── test_bayes_nonpaired.py
|
|
91
|
+
├── test_bayes_paired_laplace.py
|
|
92
|
+
├── test_bayes_paired_pg.py
|
|
93
|
+
├── test_bfda_utils.py
|
|
94
|
+
├── test_data_schemas.py
|
|
95
|
+
└── test_file_services.py
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Installation
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
pip install bayesprop
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Or with [uv](https://github.com/astral-sh/uv):
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
uv pip install bayesprop
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
For development (from source):
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
git clone https://github.com/AVoss84/bayesProp.git
|
|
114
|
+
cd bayesprop
|
|
115
|
+
uv venv --python 3.13
|
|
116
|
+
uv sync
|
|
117
|
+
source .venv/bin/activate
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Dependencies
|
|
121
|
+
|
|
122
|
+
- Python ≥ 3.13
|
|
123
|
+
- numpy, scipy, matplotlib, pandas
|
|
124
|
+
- pydantic (v2)
|
|
125
|
+
- polyagamma
|
|
126
|
+
|
|
127
|
+
## References
|
|
128
|
+
|
|
129
|
+
- Gelman, A., Carlin, J. B., Stern, H. S., Dunson, D. B., Vehtari, A. & Rubin, D. B. (2013). *Bayesian Data Analysis* (3rd ed.). Chapman & Hall/CRC.
|
|
130
|
+
- Kruschke, J. K. (2018). Rejecting or accepting parameter values in Bayesian estimation. *Advances in Methods and Practices in Psychological Science*, 1(2), 270–280.
|
|
131
|
+
- Polson, N. G., Scott, J. G. & Windle, J. (2013). Bayesian inference for logistic models using Pólya–Gamma latent variables. *JASA*, 108(504), 1339–1349.
|
|
132
|
+
- Schönbrodt, F. D. & Wagenmakers, E.-J. (2018). Bayes factor design analysis: Planning for compelling evidence. *Psychonomic Bulletin & Review*, 25(1), 128–142.
|
|
133
|
+
|
|
134
|
+
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Bayesian A/B Testing for Proportions
|
|
2
|
+
|
|
3
|
+
[](https://test.pypi.org/project/BayesProp/)
|
|
4
|
+
[](https://avoss84.github.io/bayesProp/)
|
|
5
|
+
[](https://www.python.org/)
|
|
6
|
+
[](https://github.com/AVoss84/bayesProp/actions/workflows/tests.yml)
|
|
7
|
+
[](https://github.com/AVoss84/bayesProp/actions/workflows/tests.yml)
|
|
8
|
+
|
|
9
|
+
A Python package for **Bayesian hypothesis testing** of binary (pass/fail) outcomes in A/B experiments.
|
|
10
|
+
It provides three complementary models, Savage–Dickey Bayes factors, posterior predictive checks,
|
|
11
|
+
Bayes Factor Design Analysis (BFDA) for sample-size planning, and publication-ready plots.
|
|
12
|
+
Please check out our [Getting Started](https://avoss84.github.io/bayesProp/getting_started/) guide for installation and quick examples.
|
|
13
|
+
|
|
14
|
+
## Models
|
|
15
|
+
|
|
16
|
+
| Model | Class | Method | When to use |
|
|
17
|
+
|---|---|---|---|
|
|
18
|
+
| **Non-paired Beta–Bernoulli** | `NonPairedBayesPropTest` | Conjugate Beta posterior | Independent groups, exact & fast |
|
|
19
|
+
| **Paired Logistic (Laplace)** | `PairedBayesPropTest` | MAP + Laplace approximation | Paired scores, large *n*, fast iteration |
|
|
20
|
+
| **Paired Logistic (Pólya–Gamma)** | `PairedBayesPropTestPG` | Exact Gibbs sampling | Paired scores, small *n*, exact posterior |
|
|
21
|
+
|
|
22
|
+
## Quick start
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from bayesprop.resources.bayes_paired_pg import PairedBayesPropTestPG
|
|
26
|
+
from bayesprop.utils.utils import simulate_paired_scores
|
|
27
|
+
|
|
28
|
+
# Simulate paired binary data
|
|
29
|
+
sim = simulate_paired_scores(N=200, delta_A=0.5, seed=42)
|
|
30
|
+
y_A, y_B = sim.y_A, sim.y_B
|
|
31
|
+
|
|
32
|
+
# Fit & summarise
|
|
33
|
+
model = PairedBayesPropTestPG(seed=42, n_iter=2000, burn_in=500, n_chains=4).fit(y_A, y_B)
|
|
34
|
+
print(model.summary) # PairedSummary with mean_delta, ci_95, P(A>B), …
|
|
35
|
+
|
|
36
|
+
# Hypothesis test
|
|
37
|
+
bf = model.savage_dickey_test() # SavageDickeyResult with BF_10, decision, …
|
|
38
|
+
|
|
39
|
+
# Plots
|
|
40
|
+
model.plot_posteriors()
|
|
41
|
+
model.plot_ppc(seed=42)
|
|
42
|
+
model.plot_savage_dickey()
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Package structure
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
├── pyproject.toml
|
|
49
|
+
├── justfile # task runner (just <recipe>)
|
|
50
|
+
├── .pre-commit-config.yaml # ruff format + lint hooks
|
|
51
|
+
├── data/ # evaluation datasets
|
|
52
|
+
├── docs/ # model derivations & MkDocs site
|
|
53
|
+
├── src
|
|
54
|
+
│ ├── bayesprop
|
|
55
|
+
│ │ ├── config/ # global_config, YAML configs
|
|
56
|
+
│ │ ├── resources/
|
|
57
|
+
│ │ │ ├── bayes_nonpaired.py # NonPairedBayesPropTest
|
|
58
|
+
│ │ │ ├── bayes_paired_laplace.py # PairedBayesPropTest
|
|
59
|
+
│ │ │ ├── bayes_paired_pg.py # PairedBayesPropTestPG
|
|
60
|
+
│ │ │ ├── bfda_utils.py # BFDA helpers
|
|
61
|
+
│ │ │ └── data_schemas.py # Pydantic models
|
|
62
|
+
│ │ ├── services/
|
|
63
|
+
│ │ │ └── file.py # CSV / JSON / YAML / XLSX I/O
|
|
64
|
+
│ │ └── utils/
|
|
65
|
+
│ │ └── utils.py # simulate, BFDA power curves, plots
|
|
66
|
+
│ └── notebooks/
|
|
67
|
+
│ ├── bayesian_AB_model_comparison_nonpaired.ipynb
|
|
68
|
+
│ ├── bayesian_AB_model_comparison_paired_laplace.ipynb
|
|
69
|
+
│ └── bayesian_AB_model_comparison_paired_gibbs.ipynb
|
|
70
|
+
└── tests/
|
|
71
|
+
├── test_bayes_nonpaired.py
|
|
72
|
+
├── test_bayes_paired_laplace.py
|
|
73
|
+
├── test_bayes_paired_pg.py
|
|
74
|
+
├── test_bfda_utils.py
|
|
75
|
+
├── test_data_schemas.py
|
|
76
|
+
└── test_file_services.py
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Installation
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install bayesprop
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Or with [uv](https://github.com/astral-sh/uv):
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
uv pip install bayesprop
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
For development (from source):
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
git clone https://github.com/AVoss84/bayesProp.git
|
|
95
|
+
cd bayesprop
|
|
96
|
+
uv venv --python 3.13
|
|
97
|
+
uv sync
|
|
98
|
+
source .venv/bin/activate
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Dependencies
|
|
102
|
+
|
|
103
|
+
- Python ≥ 3.13
|
|
104
|
+
- numpy, scipy, matplotlib, pandas
|
|
105
|
+
- pydantic (v2)
|
|
106
|
+
- polyagamma
|
|
107
|
+
|
|
108
|
+
## References
|
|
109
|
+
|
|
110
|
+
- Gelman, A., Carlin, J. B., Stern, H. S., Dunson, D. B., Vehtari, A. & Rubin, D. B. (2013). *Bayesian Data Analysis* (3rd ed.). Chapman & Hall/CRC.
|
|
111
|
+
- Kruschke, J. K. (2018). Rejecting or accepting parameter values in Bayesian estimation. *Advances in Methods and Practices in Psychological Science*, 1(2), 270–280.
|
|
112
|
+
- Polson, N. G., Scott, J. G. & Windle, J. (2013). Bayesian inference for logistic models using Pólya–Gamma latent variables. *JASA*, 108(504), 1339–1349.
|
|
113
|
+
- Schönbrodt, F. D. & Wagenmakers, E.-J. (2018). Bayes factor design analysis: Planning for compelling evidence. *Psychonomic Bulletin & Review*, 25(1), 128–142.
|
|
114
|
+
|
|
115
|
+
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "BayesProp"
|
|
7
|
+
version = "0.1.0.1"
|
|
8
|
+
description = "Bayesian A/B testing for proportions"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.13"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"matplotlib>=3.10.9",
|
|
13
|
+
"numpy>=2.4.4",
|
|
14
|
+
"pandas>=3.0.2",
|
|
15
|
+
"polyagamma>=2.0.2",
|
|
16
|
+
"pydantic>=2.13.3",
|
|
17
|
+
"scipy>=1.17.1",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
keywords = ["Bayesian inference", "A/B testing", "Proportions"]
|
|
21
|
+
|
|
22
|
+
authors = [
|
|
23
|
+
{ name = "Alexander Vosseler", email = "avosseler@nemetschek.com" }
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/AVoss84/bayesProp"
|
|
28
|
+
Documentation = "https://avoss84.github.io/bayesProp/"
|
|
29
|
+
Repository = "https://github.com/AVoss84/bayesProp"
|
|
30
|
+
Issues = "https://github.com/AVoss84/bayesProp/issues"
|
|
31
|
+
|
|
32
|
+
[dependency-groups]
|
|
33
|
+
dev = [
|
|
34
|
+
{include-group = "format"},
|
|
35
|
+
{include-group = "test"},
|
|
36
|
+
{include-group = "docs"},
|
|
37
|
+
"jupyter",
|
|
38
|
+
"ipykernel",
|
|
39
|
+
"pre-commit>=4.6.0",
|
|
40
|
+
]
|
|
41
|
+
format = [
|
|
42
|
+
"mypy>=1.15.0",
|
|
43
|
+
"ruff>=0.8.0",
|
|
44
|
+
]
|
|
45
|
+
test = [
|
|
46
|
+
"types-pyyaml",
|
|
47
|
+
"types-toml",
|
|
48
|
+
"isort",
|
|
49
|
+
"pytest==8.3.*",
|
|
50
|
+
"pytest-mock",
|
|
51
|
+
"pytest-timeout",
|
|
52
|
+
"pytest-cov",
|
|
53
|
+
]
|
|
54
|
+
docs = [
|
|
55
|
+
"mkdocs-material",
|
|
56
|
+
"mkdocstrings[python]",
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
[tool.setuptools]
|
|
60
|
+
package-dir = {"" = "src"}
|
|
61
|
+
|
|
62
|
+
[tool.setuptools.packages.find]
|
|
63
|
+
where = ["src"]
|
|
64
|
+
include = ["bayesprop*"]
|
|
65
|
+
|
|
66
|
+
[tool.mypy]
|
|
67
|
+
python_version = "3.13"
|
|
68
|
+
ignore_missing_imports = true
|
|
69
|
+
check_untyped_defs = true
|
|
70
|
+
warn_return_any = true
|
|
71
|
+
warn_unreachable = true
|
|
72
|
+
warn_redundant_casts = true
|
|
73
|
+
disallow_untyped_defs = true
|
|
74
|
+
|
|
75
|
+
[tool.pytest.ini_options]
|
|
76
|
+
testpaths = ["tests"]
|
|
77
|
+
addopts = "-ra -v"
|
|
78
|
+
pythonpath = ["src"]
|
|
79
|
+
python_files = ["test_*.py"]
|
|
80
|
+
python_classes = ["Test*"]
|
|
81
|
+
python_functions = ["test_*"]
|
|
82
|
+
markers = [
|
|
83
|
+
"integration: Integration tests",
|
|
84
|
+
"unit: Unit tests",
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
[tool.coverage.run]
|
|
88
|
+
source = ["src/bayesprop"]
|
|
89
|
+
|
|
90
|
+
[tool.coverage.report]
|
|
91
|
+
skip_covered = true
|
|
92
|
+
show_missing = true
|
|
93
|
+
|
|
94
|
+
[tool.ruff]
|
|
95
|
+
line-length = 120
|
|
96
|
+
indent-width = 4
|
|
97
|
+
exclude = [
|
|
98
|
+
".bzr",
|
|
99
|
+
".direnv",
|
|
100
|
+
".eggs",
|
|
101
|
+
".git",
|
|
102
|
+
".git-rewrite",
|
|
103
|
+
".hg",
|
|
104
|
+
".ipynb_checkpoints",
|
|
105
|
+
".mypy_cache",
|
|
106
|
+
".nox",
|
|
107
|
+
".pants.d",
|
|
108
|
+
".pyenv",
|
|
109
|
+
".pytest_cache",
|
|
110
|
+
".pytype",
|
|
111
|
+
".ruff_cache",
|
|
112
|
+
".svn",
|
|
113
|
+
".tox",
|
|
114
|
+
".venv",
|
|
115
|
+
".vscode",
|
|
116
|
+
"__pypackages__",
|
|
117
|
+
"_build",
|
|
118
|
+
"buck-out",
|
|
119
|
+
"build",
|
|
120
|
+
"dist",
|
|
121
|
+
"node_modules",
|
|
122
|
+
"site-packages",
|
|
123
|
+
"venv",
|
|
124
|
+
]
|
|
125
|
+
|
|
126
|
+
[tool.ruff.lint]
|
|
127
|
+
ignore = [
|
|
128
|
+
"E203", # whitespace before ':', (Black compatibility)
|
|
129
|
+
"E266", # too many '#' block (optional)
|
|
130
|
+
"E501", # line too long
|
|
131
|
+
"S101", # Use of assert detected.
|
|
132
|
+
"S311", # Standard pseudo-random generators are not suitable for cryptographic purposes
|
|
133
|
+
"PT018", # Assertion should be broken down into multiple parts
|
|
134
|
+
"D100", # Missing docstring in public module
|
|
135
|
+
"D101", # Missing docstring in public class
|
|
136
|
+
"D104", # Missing docstring in public package
|
|
137
|
+
"PT007", # Wrong values type in `pytest.mark.parametrize` expected `list` of `tuple`
|
|
138
|
+
"D212", # Multi-line docstring summary should start at the first line
|
|
139
|
+
"D200", # One-line docstring should fit on one line
|
|
140
|
+
"D205", # 1 blank line required between summary line and description
|
|
141
|
+
"D415", # First line should end with a period, question mark, or exclamation point
|
|
142
|
+
"D107", # Missing docstring in `__init__`
|
|
143
|
+
"W291", # Trailing whitespace
|
|
144
|
+
]
|
|
145
|
+
select = [
|
|
146
|
+
"S", # bandit
|
|
147
|
+
"B", # bugbear
|
|
148
|
+
"Q", # quotes
|
|
149
|
+
"PT", # pytest
|
|
150
|
+
"I", # isort
|
|
151
|
+
"E", # code style (error)
|
|
152
|
+
"W", # code style (warning)
|
|
153
|
+
"F", # pyflakes
|
|
154
|
+
"D", # docstring (pydocstyle)
|
|
155
|
+
]
|
|
156
|
+
|
|
157
|
+
[tool.ruff.lint.per-file-ignores]
|
|
158
|
+
"tests/**" = ["D102"] # Test methods don't need docstrings
|
|
159
|
+
|
|
160
|
+
[tool.ruff.lint.pydocstyle]
|
|
161
|
+
convention = "google"
|
|
162
|
+
|
|
163
|
+
[tool.ruff.format]
|
|
164
|
+
quote-style = "double"
|
|
165
|
+
indent-style = "space"
|
|
166
|
+
line-ending = "auto"
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: BayesProp
|
|
3
|
+
Version: 0.1.0.1
|
|
4
|
+
Summary: Bayesian A/B testing for proportions
|
|
5
|
+
Author-email: Alexander Vosseler <avosseler@nemetschek.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/AVoss84/bayesProp
|
|
7
|
+
Project-URL: Documentation, https://avoss84.github.io/bayesProp/
|
|
8
|
+
Project-URL: Repository, https://github.com/AVoss84/bayesProp
|
|
9
|
+
Project-URL: Issues, https://github.com/AVoss84/bayesProp/issues
|
|
10
|
+
Keywords: Bayesian inference,A/B testing,Proportions
|
|
11
|
+
Requires-Python: >=3.13
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: matplotlib>=3.10.9
|
|
14
|
+
Requires-Dist: numpy>=2.4.4
|
|
15
|
+
Requires-Dist: pandas>=3.0.2
|
|
16
|
+
Requires-Dist: polyagamma>=2.0.2
|
|
17
|
+
Requires-Dist: pydantic>=2.13.3
|
|
18
|
+
Requires-Dist: scipy>=1.17.1
|
|
19
|
+
|
|
20
|
+
# Bayesian A/B Testing for Proportions
|
|
21
|
+
|
|
22
|
+
[](https://test.pypi.org/project/BayesProp/)
|
|
23
|
+
[](https://avoss84.github.io/bayesProp/)
|
|
24
|
+
[](https://www.python.org/)
|
|
25
|
+
[](https://github.com/AVoss84/bayesProp/actions/workflows/tests.yml)
|
|
26
|
+
[](https://github.com/AVoss84/bayesProp/actions/workflows/tests.yml)
|
|
27
|
+
|
|
28
|
+
A Python package for **Bayesian hypothesis testing** of binary (pass/fail) outcomes in A/B experiments.
|
|
29
|
+
It provides three complementary models, Savage–Dickey Bayes factors, posterior predictive checks,
|
|
30
|
+
Bayes Factor Design Analysis (BFDA) for sample-size planning, and publication-ready plots.
|
|
31
|
+
Please check out our [Getting Started](https://avoss84.github.io/bayesProp/getting_started/) guide for installation and quick examples.
|
|
32
|
+
|
|
33
|
+
## Models
|
|
34
|
+
|
|
35
|
+
| Model | Class | Method | When to use |
|
|
36
|
+
|---|---|---|---|
|
|
37
|
+
| **Non-paired Beta–Bernoulli** | `NonPairedBayesPropTest` | Conjugate Beta posterior | Independent groups, exact & fast |
|
|
38
|
+
| **Paired Logistic (Laplace)** | `PairedBayesPropTest` | MAP + Laplace approximation | Paired scores, large *n*, fast iteration |
|
|
39
|
+
| **Paired Logistic (Pólya–Gamma)** | `PairedBayesPropTestPG` | Exact Gibbs sampling | Paired scores, small *n*, exact posterior |
|
|
40
|
+
|
|
41
|
+
## Quick start
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from bayesprop.resources.bayes_paired_pg import PairedBayesPropTestPG
|
|
45
|
+
from bayesprop.utils.utils import simulate_paired_scores
|
|
46
|
+
|
|
47
|
+
# Simulate paired binary data
|
|
48
|
+
sim = simulate_paired_scores(N=200, delta_A=0.5, seed=42)
|
|
49
|
+
y_A, y_B = sim.y_A, sim.y_B
|
|
50
|
+
|
|
51
|
+
# Fit & summarise
|
|
52
|
+
model = PairedBayesPropTestPG(seed=42, n_iter=2000, burn_in=500, n_chains=4).fit(y_A, y_B)
|
|
53
|
+
print(model.summary) # PairedSummary with mean_delta, ci_95, P(A>B), …
|
|
54
|
+
|
|
55
|
+
# Hypothesis test
|
|
56
|
+
bf = model.savage_dickey_test() # SavageDickeyResult with BF_10, decision, …
|
|
57
|
+
|
|
58
|
+
# Plots
|
|
59
|
+
model.plot_posteriors()
|
|
60
|
+
model.plot_ppc(seed=42)
|
|
61
|
+
model.plot_savage_dickey()
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Package structure
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
├── pyproject.toml
|
|
68
|
+
├── justfile # task runner (just <recipe>)
|
|
69
|
+
├── .pre-commit-config.yaml # ruff format + lint hooks
|
|
70
|
+
├── data/ # evaluation datasets
|
|
71
|
+
├── docs/ # model derivations & MkDocs site
|
|
72
|
+
├── src
|
|
73
|
+
│ ├── bayesprop
|
|
74
|
+
│ │ ├── config/ # global_config, YAML configs
|
|
75
|
+
│ │ ├── resources/
|
|
76
|
+
│ │ │ ├── bayes_nonpaired.py # NonPairedBayesPropTest
|
|
77
|
+
│ │ │ ├── bayes_paired_laplace.py # PairedBayesPropTest
|
|
78
|
+
│ │ │ ├── bayes_paired_pg.py # PairedBayesPropTestPG
|
|
79
|
+
│ │ │ ├── bfda_utils.py # BFDA helpers
|
|
80
|
+
│ │ │ └── data_schemas.py # Pydantic models
|
|
81
|
+
│ │ ├── services/
|
|
82
|
+
│ │ │ └── file.py # CSV / JSON / YAML / XLSX I/O
|
|
83
|
+
│ │ └── utils/
|
|
84
|
+
│ │ └── utils.py # simulate, BFDA power curves, plots
|
|
85
|
+
│ └── notebooks/
|
|
86
|
+
│ ├── bayesian_AB_model_comparison_nonpaired.ipynb
|
|
87
|
+
│ ├── bayesian_AB_model_comparison_paired_laplace.ipynb
|
|
88
|
+
│ └── bayesian_AB_model_comparison_paired_gibbs.ipynb
|
|
89
|
+
└── tests/
|
|
90
|
+
├── test_bayes_nonpaired.py
|
|
91
|
+
├── test_bayes_paired_laplace.py
|
|
92
|
+
├── test_bayes_paired_pg.py
|
|
93
|
+
├── test_bfda_utils.py
|
|
94
|
+
├── test_data_schemas.py
|
|
95
|
+
└── test_file_services.py
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Installation
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
pip install bayesprop
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Or with [uv](https://github.com/astral-sh/uv):
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
uv pip install bayesprop
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
For development (from source):
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
git clone https://github.com/AVoss84/bayesProp.git
|
|
114
|
+
cd bayesprop
|
|
115
|
+
uv venv --python 3.13
|
|
116
|
+
uv sync
|
|
117
|
+
source .venv/bin/activate
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Dependencies
|
|
121
|
+
|
|
122
|
+
- Python ≥ 3.13
|
|
123
|
+
- numpy, scipy, matplotlib, pandas
|
|
124
|
+
- pydantic (v2)
|
|
125
|
+
- polyagamma
|
|
126
|
+
|
|
127
|
+
## References
|
|
128
|
+
|
|
129
|
+
- Gelman, A., Carlin, J. B., Stern, H. S., Dunson, D. B., Vehtari, A. & Rubin, D. B. (2013). *Bayesian Data Analysis* (3rd ed.). Chapman & Hall/CRC.
|
|
130
|
+
- Kruschke, J. K. (2018). Rejecting or accepting parameter values in Bayesian estimation. *Advances in Methods and Practices in Psychological Science*, 1(2), 270–280.
|
|
131
|
+
- Polson, N. G., Scott, J. G. & Windle, J. (2013). Bayesian inference for logistic models using Pólya–Gamma latent variables. *JASA*, 108(504), 1339–1349.
|
|
132
|
+
- Schönbrodt, F. D. & Wagenmakers, E.-J. (2018). Bayes factor design analysis: Planning for compelling evidence. *Psychonomic Bulletin & Review*, 25(1), 128–142.
|
|
133
|
+
|
|
134
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/BayesProp.egg-info/PKG-INFO
|
|
4
|
+
src/BayesProp.egg-info/SOURCES.txt
|
|
5
|
+
src/BayesProp.egg-info/dependency_links.txt
|
|
6
|
+
src/BayesProp.egg-info/requires.txt
|
|
7
|
+
src/BayesProp.egg-info/top_level.txt
|
|
8
|
+
src/bayesprop/config/__init__.py
|
|
9
|
+
src/bayesprop/config/global_config.py
|
|
10
|
+
src/bayesprop/resources/__init__.py
|
|
11
|
+
src/bayesprop/resources/bayes_nonpaired.py
|
|
12
|
+
src/bayesprop/resources/bayes_paired_laplace.py
|
|
13
|
+
src/bayesprop/resources/bayes_paired_pg.py
|
|
14
|
+
src/bayesprop/resources/data_schemas.py
|
|
15
|
+
src/bayesprop/services/__init__.py
|
|
16
|
+
src/bayesprop/services/blueprint_file.py
|
|
17
|
+
src/bayesprop/services/file.py
|
|
18
|
+
src/bayesprop/utils/__init__.py
|
|
19
|
+
src/bayesprop/utils/utils.py
|
|
20
|
+
tests/test_bayes_nonpaired.py
|
|
21
|
+
tests/test_bayes_paired_laplace.py
|
|
22
|
+
tests/test_bayes_paired_pg.py
|
|
23
|
+
tests/test_bfda_utils.py
|
|
24
|
+
tests/test_data_schemas.py
|
|
25
|
+
tests/test_file_services.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bayesprop
|
|
File without changes
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
package_root = Path(__file__).resolve().parents[3]
|
|
5
|
+
|
|
6
|
+
defaults = {
|
|
7
|
+
"CODE_DIR": str(package_root / "src"),
|
|
8
|
+
"DATA_DIR": "", # external
|
|
9
|
+
"DATA_PKG_DIR": str(package_root / "data"),
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
# ------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
for env in defaults.keys():
|
|
15
|
+
if env not in os.environ:
|
|
16
|
+
os.environ[env] = defaults[env]
|
|
17
|
+
|
|
18
|
+
CODE_DIR = os.environ["CODE_DIR"]
|
|
19
|
+
DATA_DIR = os.environ["DATA_DIR"]
|
|
20
|
+
DATA_PKG_DIR = os.environ["DATA_PKG_DIR"]
|
|
21
|
+
|
|
22
|
+
# Setting for publishing the package artifacts to registry
|
|
23
|
+
# -----------------------------------------------------------
|
|
24
|
+
# package: Optional[str] = None
|
|
25
|
+
# if os.getenv("PUBLISH_ARTIFACTS", "False").lower() == "true":
|
|
26
|
+
# package = "agbe_cc.config"
|
|
27
|
+
# -----------------------------------------------------------
|
|
File without changes
|