Skip to content

Commit 6daabc2

Browse files
authored
Merge pull request #20 from genos/updates-20220125
Updates 20220125
2 parents ce52d83 + 52eefc5 commit 6daabc2

File tree

6 files changed

+247
-39
lines changed

6 files changed

+247
-39
lines changed

.gitignore

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
2+
# Created by https://www.toptal.com/developers/gitignore/api/macos,python,vim
3+
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,python,vim
4+
5+
### macOS ###
6+
# General
7+
.DS_Store
8+
.AppleDouble
9+
.LSOverride
10+
11+
# Icon must end with two \r
12+
Icon
13+
14+
# Thumbnails
15+
._*
16+
17+
# Files that might appear in the root of a volume
18+
.DocumentRevisions-V100
19+
.fseventsd
20+
.Spotlight-V100
21+
.TemporaryItems
22+
.Trashes
23+
.VolumeIcon.icns
24+
.com.apple.timemachine.donotpresent
25+
26+
# Directories potentially created on remote AFP share
27+
.AppleDB
28+
.AppleDesktop
29+
Network Trash Folder
30+
Temporary Items
31+
.apdisk
32+
33+
### Python ###
34+
# Byte-compiled / optimized / DLL files
35+
__pycache__/
36+
*.py[cod]
37+
*$py.class
38+
39+
# C extensions
40+
*.so
41+
42+
# Distribution / packaging
43+
.Python
44+
build/
45+
develop-eggs/
46+
dist/
47+
downloads/
48+
eggs/
49+
.eggs/
50+
lib/
51+
lib64/
52+
parts/
53+
sdist/
54+
var/
55+
wheels/
56+
share/python-wheels/
57+
*.egg-info/
58+
.installed.cfg
59+
*.egg
60+
MANIFEST
61+
62+
# PyInstaller
63+
# Usually these files are written by a python script from a template
64+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
65+
*.manifest
66+
*.spec
67+
68+
# Installer logs
69+
pip-log.txt
70+
pip-delete-this-directory.txt
71+
72+
# Unit test / coverage reports
73+
htmlcov/
74+
.tox/
75+
.nox/
76+
.coverage
77+
.coverage.*
78+
.cache
79+
nosetests.xml
80+
coverage.xml
81+
*.cover
82+
*.py,cover
83+
.hypothesis/
84+
.pytest_cache/
85+
cover/
86+
87+
# Translations
88+
*.mo
89+
*.pot
90+
91+
# Django stuff:
92+
*.log
93+
local_settings.py
94+
db.sqlite3
95+
db.sqlite3-journal
96+
97+
# Flask stuff:
98+
instance/
99+
.webassets-cache
100+
101+
# Scrapy stuff:
102+
.scrapy
103+
104+
# Sphinx documentation
105+
docs/_build/
106+
107+
# PyBuilder
108+
.pybuilder/
109+
target/
110+
111+
# Jupyter Notebook
112+
.ipynb_checkpoints
113+
114+
# IPython
115+
profile_default/
116+
ipython_config.py
117+
118+
# pyenv
119+
# For a library or package, you might want to ignore these files since the code is
120+
# intended to run in multiple environments; otherwise, check them in:
121+
# .python-version
122+
123+
# pipenv
124+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
125+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
126+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
127+
# install all needed dependencies.
128+
#Pipfile.lock
129+
130+
# poetry
131+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
132+
# This is especially recommended for binary packages to ensure reproducibility, and is more
133+
# commonly ignored for libraries.
134+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
135+
#poetry.lock
136+
137+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
138+
__pypackages__/
139+
140+
# Celery stuff
141+
celerybeat-schedule
142+
celerybeat.pid
143+
144+
# SageMath parsed files
145+
*.sage.py
146+
147+
# Environments
148+
.env
149+
.venv
150+
env/
151+
venv/
152+
ENV/
153+
env.bak/
154+
venv.bak/
155+
156+
# Spyder project settings
157+
.spyderproject
158+
.spyproject
159+
160+
# Rope project settings
161+
.ropeproject
162+
163+
# mkdocs documentation
164+
/site
165+
166+
# mypy
167+
.mypy_cache/
168+
.dmypy.json
169+
dmypy.json
170+
171+
# Pyre type checker
172+
.pyre/
173+
174+
# pytype static type analyzer
175+
.pytype/
176+
177+
# Cython debug symbols
178+
cython_debug/
179+
180+
# PyCharm
181+
# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
182+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
183+
# and can be added to the global gitignore or merged into this file. For a more nuclear
184+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
185+
#.idea/
186+
187+
### Vim ###
188+
# Swap
189+
[._]*.s[a-v][a-z]
190+
!*.svg # comment out if you don't need vector files
191+
[._]*.sw[a-p]
192+
[._]s[a-rt-v][a-z]
193+
[._]ss[a-gi-z]
194+
[._]sw[a-p]
195+
196+
# Session
197+
Session.vim
198+
Sessionx.vim
199+
200+
# Temporary
201+
.netrwhist
202+
*~
203+
# Auto-generated tag files
204+
tags
205+
# Persistent undo
206+
[._]*.un~
207+
208+
# End of https://www.toptal.com/developers/gitignore/api/macos,python,vim

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ Users interested in accessing the base models can do so via the `base_models_` a
115115

116116
Interested in contributing? We'd love to have your help! Please keep the following in mind:
117117

118-
* Bug fixes are welcome! Make sure you reference the issue number that is being resolved, and that all test cases in `tests` pass on both Python 2.7 and 3.4/3.5.
118+
* Bug fixes are welcome! Make sure you reference the issue number that is being resolved, and that all test cases in `tests` pass.
119119

120120
* New features are welcome as well! Any new features should include docstrings and unit tests in the `tests` directory.
121121

bayesian_bootstrap/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,7 @@ def central_credible_interval(samples, alpha=0.05):
275275
276276
Returns: Left and right interval bounds (tuple)
277277
"""
278-
tail_size = int(round(len(samples) * (alpha / 2)))
279-
samples_sorted = sorted(samples)
280-
return samples_sorted[tail_size], samples_sorted[-tail_size - 1]
278+
return np.quantile(samples, alpha / 2), np.quantile(samples, 1 - alpha / 2)
281279

282280

283281
def highest_density_interval(samples, alpha=0.05):

bayesian_bootstrap/tests/test_bootstrap.py

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import unittest
22
import numpy as np
33
import scipy
4-
import random
54
import bayesian_bootstrap as bb
65
from bayesian_bootstrap import (
76
mean,
@@ -14,6 +13,8 @@
1413
)
1514
from sklearn.linear_model import LinearRegression
1615

16+
RNG = np.random.default_rng(1337) # repeatable pseudorandomness
17+
1718

1819
class TestMoments(unittest.TestCase):
1920
def test_mean(self):
@@ -23,18 +24,18 @@ def test_mean(self):
2324
self.assertAlmostEqual(len([s for s in posterior_samples if s < 0]), 5000, delta=1000)
2425

2526
def test_variance(self):
26-
X = np.random.uniform(-1, 1, 500)
27+
X = RNG.uniform(-1, 1, 500)
2728
posterior_samples = var(X, 10000)
2829
self.assertAlmostEqual(np.mean(posterior_samples), 1 / 3.0, delta=0.05)
2930

3031
def test_self_covar(self):
31-
X = np.random.uniform(-1, 1, 500)
32+
X = RNG.uniform(-1, 1, 500)
3233
posterior_samples = covar(X, X, 10000)
3334
self.assertAlmostEqual(np.mean(posterior_samples), np.var(X), delta=0.05)
3435

3536
def test_covar(self):
36-
X = np.random.uniform(-1, 1, 500)
37-
Y = np.random.uniform(-1, 1, 500)
37+
X = RNG.uniform(-1, 1, 500)
38+
Y = RNG.uniform(-1, 1, 500)
3839
posterior_samples = covar(X, Y, 10000)
3940
self.assertAlmostEqual(np.mean(posterior_samples), 0, delta=0.05)
4041

@@ -48,25 +49,25 @@ def test_mean_resample(self):
4849
self.assertAlmostEqual(len([s for s in posterior_samples if s < 0]), 5000, delta=1000)
4950

5051
def test_var_resample(self):
51-
X = np.random.uniform(-1, 1, 500)
52+
X = RNG.uniform(-1, 1, 500)
5253
posterior_samples = bayesian_bootstrap(X, np.var, 10000, 5000, low_mem=True)
5354
self.assertAlmostEqual(np.mean(posterior_samples), 1 / 3.0, delta=0.05)
54-
X = np.random.uniform(-1, 1, 500)
55+
X = RNG.uniform(-1, 1, 500)
5556
posterior_samples = bayesian_bootstrap(X, np.var, 10000, 5000, low_mem=False)
5657
self.assertAlmostEqual(np.mean(posterior_samples), 1 / 3.0, delta=0.05)
5758

5859

5960
class TestIntervals(unittest.TestCase):
6061
def test_central_credible_interval(self):
61-
l, r = central_credible_interval(self._shuffle(list(range(10))), alpha=0.2)
62-
self.assertEqual(l, 1)
63-
self.assertEqual(r, 8)
64-
l, r = central_credible_interval(self._shuffle(list(range(10))), alpha=0.19)
65-
self.assertEqual(l, 1)
66-
self.assertEqual(r, 8)
67-
l, r = central_credible_interval(self._shuffle(list(range(20))), alpha=0.1)
68-
self.assertEqual(l, 1)
69-
self.assertEqual(r, 18)
62+
l, r = central_credible_interval(self._shuffle(range(10)), alpha=0.2)
63+
self.assertEqual(l, 0.9)
64+
self.assertEqual(r, 8.1)
65+
l, r = central_credible_interval(self._shuffle(range(10)), alpha=0.19)
66+
self.assertEqual(l, 0.855)
67+
self.assertEqual(r, 8.145)
68+
l, r = central_credible_interval(self._shuffle(range(20)), alpha=0.1)
69+
self.assertAlmostEqual(l, 0.95)
70+
self.assertEqual(r, 18.05)
7071

7172
def test_hpdi(self):
7273
l, r = highest_density_interval(self._shuffle([0, 10, 1] + [1.1] * 7), alpha=0.2)
@@ -78,14 +79,14 @@ def test_hpdi(self):
7879

7980
def _shuffle(self, x):
8081
x = list(x)
81-
random.shuffle(x)
82+
RNG.shuffle(x)
8283
return x
8384

8485

8586
class TestRegression(unittest.TestCase):
8687
def test_parameter_estimation_resampling_low_memory(self):
87-
X = np.random.uniform(0, 4, 1000)
88-
y = X + np.random.normal(0, 1, 1000)
88+
X = RNG.uniform(0, 4, 1000)
89+
y = X + RNG.normal(0, 1, 1000)
8990
m = BayesianBootstrapBagging(LinearRegression(), 10000, 1000, low_mem=True)
9091
m.fit(X.reshape(-1, 1), y)
9192
coef_samples = [b.coef_ for b in m.base_models_]
@@ -107,8 +108,8 @@ def test_parameter_estimation_resampling_low_memory(self):
107108
self.assertGreater(r, 0)
108109

109110
def test_parameter_estimation_resampling(self):
110-
X = np.random.uniform(0, 4, 1000)
111-
y = X + np.random.normal(0, 1, 1000)
111+
X = RNG.uniform(0, 4, 1000)
112+
y = X + RNG.normal(0, 1, 1000)
112113
m = BayesianBootstrapBagging(LinearRegression(), 10000, 1000, low_mem=False)
113114
m.fit(X.reshape(-1, 1), y)
114115
coef_samples = [b.coef_ for b in m.base_models_]
@@ -130,8 +131,8 @@ def test_parameter_estimation_resampling(self):
130131
self.assertGreater(r, 0)
131132

132133
def test_parameter_estimation_bayes(self):
133-
X = np.random.uniform(0, 4, 1000)
134-
y = X + np.random.normal(0, 1, 1000)
134+
X = RNG.uniform(0, 4, 1000)
135+
y = X + RNG.normal(0, 1, 1000)
135136
m = BayesianBootstrapBagging(LinearRegression(), 10000, low_mem=False)
136137
m.fit(X.reshape(-1, 1), y)
137138
coef_samples = [b.coef_ for b in m.base_models_]
@@ -153,8 +154,8 @@ def test_parameter_estimation_bayes(self):
153154
self.assertGreater(r, 0)
154155

155156
def test_parameter_estimation_bayes_low_memory(self):
156-
X = np.random.uniform(0, 4, 1000)
157-
y = X + np.random.normal(0, 1, 1000)
157+
X = RNG.uniform(0, 4, 1000)
158+
y = X + RNG.normal(0, 1, 1000)
158159
m = BayesianBootstrapBagging(LinearRegression(), 10000, low_mem=True)
159160
m.fit(X.reshape(-1, 1), y)
160161
coef_samples = [b.coef_ for b in m.base_models_]
@@ -182,12 +183,10 @@ def test_pearsonr():
182183
assert np.mean(bb.pearsonr(x, y, 10000)) == 1
183184
assert np.mean(bb.pearsonr(x, -y, 10000)) == -1
184185

185-
np.random.seed(1337)
186186
x = [0, 1, 3, 6]
187187
y = [1, 2, 5, 7]
188188
assert np.isclose(np.mean(bb.pearsonr(x, y, 10000)), scipy.stats.pearsonr(x, y)[0], atol=0.001)
189189

190-
np.random.seed(1337)
191190
x = np.linspace(-10, 10, 10000)
192191
y = np.abs(x)
193192
assert np.isclose(scipy.stats.pearsonr(x, y)[0], np.mean(bb.pearsonr(x, y, 1000)), atol=0.001)

requirements.txt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
numpy
2-
scipy
3-
pandas
4-
scikit-learn
5-
tqdm
1+
numpy>=1.22.1
2+
scipy>=1.7.3
3+
scikit-learn>=1.0.2
4+
tqdm>=4.62.3

0 commit comments

Comments
 (0)