Skip to content

Commit 243f366

Browse files
committed
nb init
1 parent 4875104 commit 243f366

File tree

2 files changed

+1092
-0
lines changed

2 files changed

+1092
-0
lines changed

examples/time_series/Time_Series_Generative_Graph.ipynb

Lines changed: 852 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
---
2+
jupytext:
3+
text_representation:
4+
extension: .md
5+
format_name: myst
6+
format_version: 0.13
7+
kernelspec:
8+
display_name: pymc_env
9+
language: python
10+
name: python3
11+
---
12+
13+
(arima_garch_1_1)=
14+
# Time Series Models Derived From a Generative Graph
15+
16+
:::{post} March, 2024
17+
:tags: time-series,
18+
:category: intermediate, reference
19+
:author: Juan Orduz and Ricardo Vieira
20+
:::
21+
22+
```{code-cell} ipython3
23+
import arviz as az
24+
import matplotlib.pyplot as plt
25+
import numpy as np
26+
import pymc as pm
27+
import pytensor
28+
import pytensor.tensor as pt
29+
30+
from pymc.pytensorf import collect_default_updates
31+
32+
az.style.use("arviz-darkgrid")
33+
plt.rcParams["figure.figsize"] = [12, 7]
34+
plt.rcParams["figure.dpi"] = 100
35+
plt.rcParams["figure.facecolor"] = "white"
36+
37+
%config InlineBackend.figure_format = "retina"
38+
39+
rng = np.random.default_rng(42)
40+
```
41+
42+
```{code-cell} ipython3
43+
lags = 2
44+
trials = 100
45+
46+
47+
def ar_dist(ar_init, rho, sigma, size):
48+
def ar_step(x_tm2, x_tm1, rho, sigma):
49+
mu = x_tm1 * rho[0] + x_tm2 * rho[1]
50+
x = mu + pm.Normal.dist(sigma=sigma)
51+
return x, collect_default_updates([x])
52+
53+
ar_innov, _ = pytensor.scan(
54+
fn=ar_step,
55+
outputs_info=[{"initial": ar_init, "taps": range(-lags, 0)}],
56+
non_sequences=[rho, sigma],
57+
n_steps=trials - lags,
58+
strict=True,
59+
)
60+
61+
return ar_innov
62+
```
63+
64+
```{code-cell} ipython3
65+
coords = {
66+
"lags": range(-lags, 0),
67+
"steps": range(trials - lags),
68+
"trials": range(trials),
69+
}
70+
with pm.Model(coords=coords, check_bounds=False) as model:
71+
rho = pm.Normal(name="rho", mu=0, sigma=0.2, dims=("lags",))
72+
sigma = pm.HalfNormal(name="sigma", sigma=0.2)
73+
74+
ar_init_obs = pm.MutableData(name="ar_init_obs", value=np.zeros(lags), dims=("lags",))
75+
ar_init = pm.Normal(name="ar_init", observed=ar_init_obs, dims=("lags",))
76+
77+
ar_innov_obs = pm.MutableData("ar_innov_obs", np.zeros(trials - lags), dims=("steps",))
78+
ar_innov = pm.CustomDist(
79+
"ar_dist",
80+
ar_init,
81+
rho,
82+
sigma,
83+
dist=ar_dist,
84+
observed=ar_innov_obs,
85+
dims=("steps",),
86+
)
87+
88+
ar = pm.Deterministic(
89+
name="ar", var=pt.concatenate([ar_init, ar_innov], axis=-1), dims=("trials",)
90+
)
91+
92+
93+
pm.model_to_graphviz(model)
94+
```
95+
96+
## Prior
97+
98+
```{code-cell} ipython3
99+
with model:
100+
prior = pm.sample_prior_predictive(samples=100, random_seed=rng)
101+
```
102+
103+
```{code-cell} ipython3
104+
_, ax = plt.subplots()
105+
for i, hdi_prob in enumerate((0.94, 0.64), 1):
106+
hdi = az.hdi(prior.prior["ar"], hdi_prob=hdi_prob)["ar"]
107+
lower = hdi.sel(hdi="lower")
108+
upper = hdi.sel(hdi="higher")
109+
ax.fill_between(
110+
x=np.arange(trials),
111+
y1=lower,
112+
y2=upper,
113+
alpha=(i - 0.2) * 0.2,
114+
color="C0",
115+
label=f"{hdi_prob:.0%} HDI",
116+
)
117+
ax.plot(prior.prior["ar"].mean(("chain", "draw")), color="C0", label="Mean")
118+
ax.legend(loc="upper right")
119+
ax.set_xlabel("trials")
120+
ax.set_title("AR(2) Prior Samples", fontsize=18, fontweight="bold")
121+
```
122+
123+
```{code-cell} ipython3
124+
fig, ax = plt.subplots(
125+
nrows=5, ncols=1, figsize=(12, 12), sharex=True, sharey=True, layout="constrained"
126+
)
127+
chosen_draw = 2
128+
for i, axi in enumerate(ax, start=chosen_draw):
129+
axi.plot(
130+
prior.prior["ar"].isel(draw=i, chain=0),
131+
color="C0" if i == chosen_draw else "black",
132+
)
133+
axi.set_title(f"Sample {i}", fontsize=18, fontweight="bold")
134+
ax[-1].set_xlabel("trials")
135+
```
136+
137+
## Posterior
138+
139+
```{code-cell} ipython3
140+
prior_draw = prior.prior.isel(chain=0, draw=chosen_draw)
141+
142+
ar_init_obs.set_value(prior_draw["ar"].values[:lags])
143+
ar_innov_obs.set_value(prior_draw["ar"].values[lags:])
144+
ar_obs = prior_draw["ar"].to_numpy()
145+
rho_true = prior_draw["rho"].to_numpy()
146+
sigma_true = prior_draw["sigma"].to_numpy()
147+
148+
print(f"rho_true={np.round(rho_true, 3)}, {sigma_true=:.3f}")
149+
```
150+
151+
```{code-cell} ipython3
152+
with model:
153+
trace = pm.sample(random_seed=rng)
154+
```
155+
156+
```{code-cell} ipython3
157+
axes = az.plot_trace(
158+
data=trace,
159+
var_names=["rho", "sigma"],
160+
compact=True,
161+
lines=[
162+
("rho", {}, rho_true),
163+
("sigma", {}, sigma_true),
164+
],
165+
backend_kwargs={"figsize": (12, 5), "layout": "constrained"},
166+
)
167+
plt.gcf().suptitle("AR(2) Model Trace", fontsize=18, fontweight="bold")
168+
```
169+
170+
```{code-cell} ipython3
171+
axes = az.plot_posterior(
172+
trace, var_names=["rho", "sigma"], ref_val=[*rho_true, sigma_true], figsize=(15, 5)
173+
)
174+
plt.gcf().suptitle("AR(2) Model Parameters Posterior", fontsize=18, fontweight="bold")
175+
```
176+
177+
## Posterior Predictive
178+
179+
```{code-cell} ipython3
180+
with model:
181+
post_pred = pm.sample_posterior_predictive(trace, random_seed=rng)
182+
```
183+
184+
```{code-cell} ipython3
185+
post_pred_ar = post_pred.posterior_predictive["ar"]
186+
187+
_, ax = plt.subplots()
188+
for i, hdi_prob in enumerate((0.94, 0.64), 1):
189+
hdi = az.hdi(post_pred_ar, hdi_prob=hdi_prob)["ar"]
190+
lower = hdi.sel(hdi="lower")
191+
upper = hdi.sel(hdi="higher")
192+
ax.fill_between(
193+
x=np.arange(trials),
194+
y1=lower,
195+
y2=upper,
196+
alpha=(i - 0.2) * 0.2,
197+
color="C0",
198+
label=f"{hdi_prob:.0%} HDI",
199+
)
200+
ax.plot(prior.prior["ar"].mean(("chain", "draw")), color="C0", label="Mean")
201+
ax.plot(ar_obs, color="black", label="Observed")
202+
ax.legend(loc="upper right")
203+
ax.set_xlabel("trials")
204+
ax.set_title("AR(2) Posterior Predictive Samples", fontsize=18, fontweight="bold")
205+
```
206+
207+
```{code-cell} ipython3
208+
fig, ax = plt.subplots(
209+
nrows=5, ncols=1, figsize=(12, 12), sharex=True, sharey=True, layout="constrained"
210+
)
211+
for i, axi in enumerate(ax):
212+
axi.plot(post_pred.posterior_predictive["ar"].isel(draw=i, chain=0), color="C0")
213+
axi.set_title(f"Sample {i}")
214+
215+
ax[-1].set_xlabel("trials")
216+
217+
fig.suptitle("AR(2) Posterior Predictive Samples", fontsize=18, fontweight="bold", y=1.05)
218+
```
219+
220+
## Authors
221+
- Authored by [Juan Orduz](https://juanitorduz.github.io/) and [Ricardo Vieira](https://github.com/ricardoV94) in March 2024
222+
223+
+++
224+
225+
## References
226+
:::{bibliography}
227+
:filter: docname in docnames
228+
:::
229+
230+
+++
231+
232+
## Watermark
233+
234+
```{code-cell} ipython3
235+
%load_ext watermark
236+
%watermark -n -u -v -iv -w -p pytensor
237+
```
238+
239+
:::{include} ../page_footer.md
240+
:::

0 commit comments

Comments
 (0)