Skip to content

Commit a514485

Browse files
author
Jash2606
committed
2 parents 647050a + 4515f49 commit a514485

File tree

10 files changed

+427
-133
lines changed

10 files changed

+427
-133
lines changed

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ ci:
33

44
repos:
55
- repo: https://github.com/psf/black
6-
rev: 23.7.0
6+
rev: 24.4.2
77
hooks:
88
- id: black-jupyter
99
- repo: https://github.com/nbQA-dev/nbQA
10-
rev: 1.7.0
10+
rev: 1.8.5
1111
hooks:
1212
- id: nbqa-isort
1313
additional_dependencies: [isort==5.6.4]
@@ -99,7 +99,7 @@ repos:
9999
language: pygrep
100100
types_or: [markdown, rst, jupyter]
101101
- repo: https://github.com/mwouts/jupytext
102-
rev: v1.15.1
102+
rev: v1.16.3
103103
hooks:
104104
- id: jupytext
105105
files: ^examples/.+\.ipynb$

examples/ode_models/ODE_with_manual_gradients.ipynb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,9 @@
189189
" ret = np.zeros(\n",
190190
" (self._n_states, self._n_odeparams + self._n_ivs)\n",
191191
" ) # except the following entries\n",
192-
" ret[\n",
193-
" 0, 0\n",
194-
" ] = X # \\frac{\\partial [\\alpha X - \\beta XY]}{\\partial \\alpha}, and so on...\n",
192+
" ret[0, 0] = (\n",
193+
" X # \\frac{\\partial [\\alpha X - \\beta XY]}{\\partial \\alpha}, and so on...\n",
194+
" )\n",
195195
" ret[0, 1] = -X * Y\n",
196196
" ret[1, 2] = -Y\n",
197197
" ret[1, 3] = X * Y\n",

examples/ode_models/ODE_with_manual_gradients.myst.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ class LotkaVolterraModel:
157157
ret = np.zeros(
158158
(self._n_states, self._n_odeparams + self._n_ivs)
159159
) # except the following entries
160-
ret[
161-
0, 0
162-
] = X # \frac{\partial [\alpha X - \beta XY]}{\partial \alpha}, and so on...
160+
ret[0, 0] = (
161+
X # \frac{\partial [\alpha X - \beta XY]}{\partial \alpha}, and so on...
162+
)
163163
ret[0, 1] = -X * Y
164164
ret[1, 2] = -Y
165165
ret[1, 3] = X * Y

examples/samplers/MLDA_introduction.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"\n",
6464
"[Gravity surveying](./MLDA_gravity_surveying.ipynb): In this notebook, we use MLDA to solve a 2-dimensional gravity surveying inverse problem. Evaluating the likelihood requires solving a PDE, which we do using [scipy](https://www.scipy.org/). We also compare the performance of MLDA with other PyMC samplers (Metropolis, DEMetropolisZ).\n",
6565
"\n",
66-
"[Variance reduction 1](./MLDA_variance_reduction_linear_regression.ipynb) and [Variance reduction 2](https://github.com/alan-turing-institute/pymc/blob/mlda_all_notebooks/docs/source/notebooks/MLDA_variance_reduction_groundwater.ipynb) (external link): Those two notebooks demonstrate the variance reduction feature in a linear regression model and a groundwater flow model. This feature allows the user to define a quantity of interest that they need to estimate using the MCMC samples. It then collects those quantities of interest, as well as differences of these quantities between levels, during MLDA sampling. The collected quentities can then be used to produce an estimate which has lower variance than a standard estimate that uses samples from the fine chain only. The first notebook does not have external dependencies, while the second one requires FEniCS. Note that the second notebook is outside the core PyMC repository because FEniCS is not a PyMC dependency.\n",
66+
"[Variance reduction 1](./MLDA_variance_reduction_linear_regression.ipynb) and [Variance reduction 2](https://github.com/alan-turing-institute/pymc3/blob/mlda_all_notebooks/docs/source/notebooks/MLDA_variance_reduction_groundwater.ipynb) (external link): Those two notebooks demonstrate the variance reduction feature in a linear regression model and a groundwater flow model. This feature allows the user to define a quantity of interest that they need to estimate using the MCMC samples. It then collects those quantities of interest, as well as differences of these quantities between levels, during MLDA sampling. The collected quentities can then be used to produce an estimate which has lower variance than a standard estimate that uses samples from the fine chain only. The first notebook does not have external dependencies, while the second one requires FEniCS. Note that the second notebook is outside the core PyMC repository because FEniCS is not a PyMC dependency.\n",
6767
"\n",
6868
"[Adaptive error model](https://github.com/alan-turing-institute/pymc3/blob/mlda_all_notebooks/docs/source/notebooks/MLDA_adaptive_error_model.ipynb) (external link): In this notebook we use MLDA to tackle another inverse problem; groundwarer flow modeling. The aim is to infer the posterior distribution of model parameters (hydraulic conductivity) given data (measurements of hydraulic head). In this example we make use of PyTensor Ops in order to define a \"black box\" likelihood, i.e. a likelihood that uses external code. Specifically, our likelihood uses the [FEniCS](https://fenicsproject.org/) library to solve a PDE. This is a common scenario, as PDEs of this type are slow to solve with scipy or other standard libraries. Note that this notebook is outside the core PyMC repository because FEniCS is not a PyMC dependency. We employ the adaptive error model (AEM) feature and compare the performance of basic MLDA with AEM-enhanced MLDA. The idea of Adaptive Error Model (AEM) is to estimate the mean and variance of the forward-model error between adjacent levels, i.e. estimate the bias of the coarse forward model compared to the fine forward model, and use those estimates to correct the coarse model. Using the technique should improve ESS/sec on the fine level.\n",
6969
"\n",

examples/samplers/MLDA_introduction.myst.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Please note that the MLDA sampler is new in PyMC. The user should be extra criti
5757

5858
[Gravity surveying](./MLDA_gravity_surveying.ipynb): In this notebook, we use MLDA to solve a 2-dimensional gravity surveying inverse problem. Evaluating the likelihood requires solving a PDE, which we do using [scipy](https://www.scipy.org/). We also compare the performance of MLDA with other PyMC samplers (Metropolis, DEMetropolisZ).
5959

60-
[Variance reduction 1](./MLDA_variance_reduction_linear_regression.ipynb) and [Variance reduction 2](https://github.com/alan-turing-institute/pymc/blob/mlda_all_notebooks/docs/source/notebooks/MLDA_variance_reduction_groundwater.ipynb) (external link): Those two notebooks demonstrate the variance reduction feature in a linear regression model and a groundwater flow model. This feature allows the user to define a quantity of interest that they need to estimate using the MCMC samples. It then collects those quantities of interest, as well as differences of these quantities between levels, during MLDA sampling. The collected quentities can then be used to produce an estimate which has lower variance than a standard estimate that uses samples from the fine chain only. The first notebook does not have external dependencies, while the second one requires FEniCS. Note that the second notebook is outside the core PyMC repository because FEniCS is not a PyMC dependency.
60+
[Variance reduction 1](./MLDA_variance_reduction_linear_regression.ipynb) and [Variance reduction 2](https://github.com/alan-turing-institute/pymc3/blob/mlda_all_notebooks/docs/source/notebooks/MLDA_variance_reduction_groundwater.ipynb) (external link): Those two notebooks demonstrate the variance reduction feature in a linear regression model and a groundwater flow model. This feature allows the user to define a quantity of interest that they need to estimate using the MCMC samples. It then collects those quantities of interest, as well as differences of these quantities between levels, during MLDA sampling. The collected quentities can then be used to produce an estimate which has lower variance than a standard estimate that uses samples from the fine chain only. The first notebook does not have external dependencies, while the second one requires FEniCS. Note that the second notebook is outside the core PyMC repository because FEniCS is not a PyMC dependency.
6161

6262
[Adaptive error model](https://github.com/alan-turing-institute/pymc3/blob/mlda_all_notebooks/docs/source/notebooks/MLDA_adaptive_error_model.ipynb) (external link): In this notebook we use MLDA to tackle another inverse problem; groundwarer flow modeling. The aim is to infer the posterior distribution of model parameters (hydraulic conductivity) given data (measurements of hydraulic head). In this example we make use of PyTensor Ops in order to define a "black box" likelihood, i.e. a likelihood that uses external code. Specifically, our likelihood uses the [FEniCS](https://fenicsproject.org/) library to solve a PDE. This is a common scenario, as PDEs of this type are slow to solve with scipy or other standard libraries. Note that this notebook is outside the core PyMC repository because FEniCS is not a PyMC dependency. We employ the adaptive error model (AEM) feature and compare the performance of basic MLDA with AEM-enhanced MLDA. The idea of Adaptive Error Model (AEM) is to estimate the mean and variance of the forward-model error between adjacent levels, i.e. estimate the bias of the coarse forward model compared to the fine forward model, and use those estimates to correct the coarse model. Using the technique should improve ESS/sec on the fine level.
6363

examples/samplers/samplers_mvnormal.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
normalized effective sampling rates.
77
"""
88

9-
109
import time
1110

1211
import arviz as az

examples/spatial/nyc_bym.ipynb

Lines changed: 372 additions & 100 deletions
Large diffs are not rendered by default.

examples/spatial/nyc_bym.myst.md

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ with pm.Model(coords=coords) as BYM_model:
329329
theta = pm.Normal("theta", 0, 1, dims="area_idx")
330330
331331
# spatially structured random effect
332-
phi = pm.ICAR("phi", W=W_nyc)
332+
phi = pm.ICAR("phi", W=W_nyc, dims="area_idx")
333333
334334
# joint variance of random effects
335335
sigma = pm.HalfNormal("sigma", 1)
@@ -338,11 +338,15 @@ with pm.Model(coords=coords) as BYM_model:
338338
rho = pm.Beta("rho", 0.5, 0.5)
339339
340340
# the bym component - it mixes a spatial and a random effect
341-
mixture = pt.sqrt(1 - rho) * theta + pt.sqrt(rho / scaling_factor) * phi
341+
mixture = pm.Deterministic(
342+
"mixture", pt.sqrt(1 - rho) * theta + pt.sqrt(rho / scaling_factor) * phi, dims="area_idx"
343+
)
342344
343345
# exponential link function to ensure
344346
# predictions are positive
345-
mu = pt.exp(log_E + beta0 + beta1 * fragment_index + sigma * mixture)
347+
mu = pm.Deterministic(
348+
"mu", pt.exp(log_E + beta0 + beta1 * fragment_index + sigma * mixture), dims="area_idx"
349+
)
346350
347351
y_i = pm.Poisson("y_i", mu, observed=y)
348352
```
@@ -361,7 +365,7 @@ with BYM_model:
361365
We can evaluate the sampler in several ways. First, it looks like all our chains converged. All parameters have rhat values very close to one.
362366

363367
```{code-cell} ipython3
364-
rhat = az.summary(idata).r_hat.values
368+
rhat = az.summary(idata, kind="diagnostics").r_hat.values
365369
sum(rhat > 1.03)
366370
```
367371

@@ -380,29 +384,33 @@ Our trace plot also indicates there is a small effect of social fragmentation on
380384

381385
The payoff of all this work is that we can now visualize what it means to decompose the variance into explanatory, spatial and unstructured parts. One way to make this vivid is to inspect each component of the model individually. We'll see what the model thinks NYC should look like if spatial effects were the only source of variance, then we'll turn to the explanatory effect and finally the random effect.
382386

383-
We'll extract the means of several parameters to generate predictions. In the first case, we'll visualize only the predictions that come from the spatial component of the model. In other words, we are assuming $\rho = 1$ and we ignore $\theta$ and social fragmentation.
387+
In the first case, we'll visualize only the predictions that come from the spatial component of the model. In other words, we are assuming $\rho = 1$ and we ignore $\theta$ and social fragmentation.
384388

385-
```{code-cell} ipython3
386-
phi_pred = idata.posterior.phi.mean(("chain", "draw")).values
387-
beta0_pred = idata.posterior.beta0.mean(("chain", "draw")).values
388-
sigma_pred = idata.posterior.sigma.mean(("chain", "draw")).values
389-
y_predict = np.exp(log_E + beta0_pred + sigma_pred * (1 / scaling_factor) * phi_pred)
390-
```
389+
+++
391390

392391
Then we'll overlay our predictions onto the same {ref}`adjacency map we built earlier <adjacency-map>`.
393392

394393
```{code-cell} ipython3
394+
# draw posterio
395+
396+
with pm.do(BYM_model, {"rho": 1.0, "beta1": 0}):
397+
y_predict = pm.sample_posterior_predictive(
398+
idata, var_names=["mu", "mixture"], predictions=True, extend_inferencedata=False
399+
)
400+
401+
y_spatial_pred = y_predict.predictions.mu.mean(dim=["chain", "draw"]).values
402+
395403
plt.figure(figsize=(10, 8))
396404
nx.draw_networkx(
397405
G_nyc,
398406
pos=pos,
399-
node_color=y_predict,
407+
node_color=y_spatial_pred,
400408
cmap="plasma",
401409
vmax=30,
402410
width=0.5,
403411
alpha=0.6,
404412
with_labels=False,
405-
node_size=20 + 3 * y_predict,
413+
node_size=20 + 3 * y_spatial_pred,
406414
)
407415
```
408416

@@ -413,40 +421,53 @@ Spatial smoothing is especially useful for forecasting. Imagine there was a low-
413421
We can notice that there are three neighborhoods of risk, represented by large yellow clusters, that are well-captured. This suggests that a lot of the explanation for traffic accidents has to do with unidentified but spatially structured causes. By contrast, the social fragmentation index only explains a single neighborhood of risk in the bottom center of the map (with a few small pockets of success elsewhere).
414422

415423
```{code-cell} ipython3
416-
beta1_pred = idata.posterior.beta1.mean(("chain", "draw")).values
417-
y_predict = np.exp(log_E + beta0_pred + beta1_pred * fragment_index)
424+
with pm.do(
425+
BYM_model,
426+
{
427+
"sigma": 0.0,
428+
},
429+
):
430+
y_predict = pm.sample_posterior_predictive(
431+
idata, var_names=["mu", "mixture"], predictions=True, extend_inferencedata=False
432+
)
433+
434+
y_frag_pred = y_predict.predictions.mu.mean(dim=["chain", "draw"]).values
418435
419436
plt.figure(figsize=(10, 8))
420437
nx.draw_networkx(
421438
G_nyc,
422439
pos=pos,
423-
node_color=y_predict,
440+
node_color=y_frag_pred,
424441
cmap="plasma",
425442
vmax=30,
426443
width=0.5,
427444
alpha=0.6,
428445
with_labels=False,
429-
node_size=20 + 3 * y_predict,
446+
node_size=20 + 3 * y_frag_pred,
430447
)
431448
```
432449

433450
Finally, we might look at the unstructured variance by assuming $\rho = 0$. If our model managed to partition variance successfully, there should not be too many spatial clusters left over in the unstructured variance. Instead, variance should be scattered all over the map.
434451

435452
```{code-cell} ipython3
436-
theta_pred = idata.posterior.theta.mean(("chain", "draw")).values
437-
y_predict = np.exp(log_E + beta0_pred + sigma_pred * theta_pred)
453+
with pm.do(BYM_model, {"rho": 0.0, "beta1": 0}):
454+
y_predict = pm.sample_posterior_predictive(
455+
idata, var_names=["mu", "mixture"], predictions=True, extend_inferencedata=False
456+
)
457+
458+
y_unspatial_pred = y_predict.predictions.mu.mean(dim=["chain", "draw"]).values
438459
439460
plt.figure(figsize=(10, 8))
440461
nx.draw_networkx(
441462
G_nyc,
442463
pos=pos,
443-
node_color=y_predict,
464+
node_color=y_unspatial_pred,
444465
cmap="plasma",
445466
vmax=30,
446467
width=0.5,
447468
alpha=0.6,
448469
with_labels=False,
449-
node_size=20 + 3 * y_predict,
470+
node_size=20 + 3 * y_unspatial_pred,
450471
)
451472
```
452473

scripts/rerun.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
python scripts/rerun.py --fp_notebook=examples/case_studies/BEST.ipynb --commit_to=rerun-best --push_to=mine
1515
```
1616
"""
17+
1718
import argparse
1819
import logging
1920
import pathlib

sphinxext/thumbnail_extractor.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
44
Modified from the seaborn project, which modified the mpld3 project.
55
"""
6+
67
import base64
78
import json
89
import os

0 commit comments

Comments
 (0)