@@ -43,13 +43,13 @@ logger.setLevel(logging.CRITICAL)
43434444```
454546-This lecture. uses Bayesian methods offered by [pymc](https://www.pymc.io/projects/docs/en/stable/) and [numpyro](https://num.pyro.ai/en/stable/) to make statistical inferences about two parameters of a univariate first-order autoregression.
46+This lecture uses Bayesian methods offered by [pymc](https://www.pymc.io/projects/docs/en/stable/) and [numpyro](https://num.pyro.ai/en/stable/) to make statistical inferences about two parameters of a univariate first-order autoregression.
474748484949The model is a good laboratory for illustrating
5050consequences of alternative ways of modeling the distribution of the initial $y_0$:
515152-- As a fixed number.
52+- As a fixed number
53535454- As a random variable drawn from the stationary distribution of the $\{y_t\}$ stochastic process
5555@@ -65,8 +65,6 @@ $\{\epsilon_{t+1}\}$ is a sequence of i.i.d. normal random variables with mean $
65656666The second component of the statistical model is
676768-and
69-7068$$
7169y_0 \sim {\cal N}(\mu_0, \sigma_0^2)
7270$$ (eq:themodel_2)
@@ -172,7 +170,7 @@ Now we shall use Bayes' law to construct a posterior distribution, conditioning
172170173171First we'll use **pymc4**.
174172175-## `PyMC` Implementation
173+## PyMC Implementation
176174177175For a normal distribution in `pymc`,
178176$var = 1/\tau = \sigma^{2}$.
@@ -183,15 +181,15 @@ AR1_model = pmc.Model()
183181184182with AR1_model:
185183186- #start with priors
187- rho = pmc.Uniform('rho',lower=-1.,upper=1.) #assume stable rho
184+ # Start with priors
185+ rho = pmc.Uniform('rho', lower=-1., upper=1.) # Assume stable rho
188186 sigma = pmc.HalfNormal('sigma', sigma = np.sqrt(10))
189187190188 # Expected value of y at the next period (rho * y)
191- yhat = rho*y[:-1]
189+ yhat = rho * y[:-1]
192190193- # Likelihood of the actual realization.
194- y_like = pmc.Normal('y_obs', mu = yhat, sigma=sigma, observed=y[1:])
191+ # Likelihood of the actual realization
192+ y_like = pmc.Normal('y_obs', mu=yhat, sigma=sigma, observed=y[1:])
195193```
196194197195```{code-cell} ipython3
@@ -213,13 +211,12 @@ This is is a symptom of the classic **Hurwicz bias** for first order autorgress
213211The Hurwicz bias is worse the smaller is the sample (see {cite}`Orcutt_Winokur_69`.)
214212215213216-Be that as it may, here is more information about the posterior
214+Be that as it may, here is more information about the posterior.
217215218216```{code-cell} ipython3
219217with AR1_model:
220218 summary = az.summary(trace, round_to=4)
221219222-# print
223220summary
224221```
225222@@ -238,17 +235,17 @@ AR1_model_y0 = pmc.Model()
238235239236with AR1_model_y0:
240237241- #start with priors
242- rho = pmc.Uniform('rho',lower=-1.,upper=1.) #assume stable rho
238+ # Start with priors
239+ rho = pmc.Uniform('rho', lower=-1., upper=1.) # Assume stable rho
243240 sigma = pmc.HalfNormal('sigma', sigma=np.sqrt(10))
244241245- #standard deviation of ergodic y
246- y_sd = sigma/np.sqrt(1-rho**2)
242+ # Standard deviation of ergodic y
243+ y_sd = sigma / np.sqrt(1 - rho**2)
247244248- #yhat
249- yhat = rho*y[:-1]
250- y_data = pmc.Normal('y_obs', mu = yhat, sigma=sigma, observed=y[1:])
251- y0_data = pmc.Normal('y0_obs', mu = 0., sigma=y_sd, observed=y[0])
245+ # yhat
246+ yhat = rho * y[:-1]
247+ y_data = pmc.Normal('y_obs', mu=yhat, sigma=sigma, observed=y[1:])
248+ y0_data = pmc.Normal('y0_obs', mu=0., sigma=y_sd, observed=y[0])
252249```
253250254251```{code-cell} ipython3
@@ -257,7 +254,7 @@ with AR1_model_y0:
257254with AR1_model_y0:
258255 trace_y0 = pmc.sample(50000, tune=10000, return_inferencedata=True)
259256260-# grey vertical lines are the cases of divergence
257+# Grey vertical lines are the cases of divergence
261258```
262259263260```{code-cell} ipython3
@@ -269,7 +266,6 @@ with AR1_model_y0:
269266with AR1_model:
270267 summary_y0 = az.summary(trace_y0, round_to=4)
271268272-# print
273269summary_y0
274270```
275271@@ -284,7 +280,7 @@ We'll return to this issue after we use `numpyro` to compute posteriors under ou
284280285281We'll now repeat the calculations using `numpyro`.
286282287-## `Numpyro` Implementation
283+## Numpyro Implementation
288284289285```{code-cell} ipython3
290286@@ -293,25 +289,25 @@ def plot_posterior(sample):
293289 """
294290 Plot trace and histogram
295291 """
296- # to np array
292+ # To np array
297293 rhos = sample['rho']
298294 sigmas = sample['sigma']
299295 rhos, sigmas, = np.array(rhos), np.array(sigmas)
300296301- fig, axs = plt.subplots(2,2, figsize=(17,6))
302- # plot trace
303- axs[0,0].plot(rhos) # rho
304- axs[1,0].plot(sigmas) # sigma
297+ fig, axs = plt.subplots(2, 2, figsize=(17, 6))
298+ # Plot trace
299+ axs[0, 0].plot(rhos) # rho
300+ axs[1, 0].plot(sigmas) # sigma
305301306- # plot posterior
307- axs[0,1].hist(rhos, bins=50, density=True, alpha=0.7)
308- axs[0,1].set_xlim([0,1])
309- axs[1,1].hist(sigmas, bins=50, density=True, alpha=0.7)
302+ # Plot posterior
303+ axs[0, 1].hist(rhos, bins=50, density=True, alpha=0.7)
304+ axs[0, 1].set_xlim([0, 1])
305+ axs[1, 1].hist(sigmas, bins=50, density=True, alpha=0.7)
310306311- axs[0,0].set_title("rho")
312- axs[0,1].set_title("rho")
313- axs[1,0].set_title("sigma")
314- axs[1,1].set_title("sigma")
307+ axs[0, 0].set_title("rho")
308+ axs[0, 1].set_title("rho")
309+ axs[1, 0].set_title("sigma")
310+ axs[1, 1].set_title("sigma")
315311 plt.show()
316312```
317313@@ -322,7 +318,7 @@ def AR1_model(data):
322318 sigma = numpyro.sample('sigma', dist.HalfNormal(scale=np.sqrt(10)))
323319324320 # Expected value of y at the next period (rho * y)
325- yhat = rho*data[:-1]
321+ yhat = rho * data[:-1]
326322327323 # Likelihood of the actual realization.
328324 y_data = numpyro.sample('y_obs', dist.Normal(loc=yhat, scale=sigma), obs=data[1:])
@@ -332,13 +328,13 @@ def AR1_model(data):
332328```{code-cell} ipython3
333329:tag: [hide-output]
334330335-# make jnp array
331+# Make jnp array
336332y = jnp.array(y)
337333338-# set NUTS kernal
334+# Set NUTS kernal
339335NUTS_kernel = numpyro.infer.NUTS(AR1_model)
340336341-# run MCMC
337+# Run MCMC
342338mcmc = numpyro.infer.MCMC(NUTS_kernel, num_samples=50000, num_warmup=10000, progress_bar=False)
343339mcmc.run(rng_key=random.PRNGKey(1), data=y)
344340```
@@ -361,15 +357,15 @@ Here's the new code to achieve this.
361357362358```{code-cell} ipython3
363359def AR1_model_y0(data):
364- # set prior
360+ # Set prior
365361 rho = numpyro.sample('rho', dist.Uniform(low=-1., high=1.))
366362 sigma = numpyro.sample('sigma', dist.HalfNormal(scale=np.sqrt(10)))
367363368- #standard deviation of ergodic y
369- y_sd = sigma/jnp.sqrt(1-rho**2)
364+ # Standard deviation of ergodic y
365+ y_sd = sigma / jnp.sqrt(1 - rho**2)
370366371367 # Expected value of y at the next period (rho * y)
372- yhat = rho*data[:-1]
368+ yhat = rho * data[:-1]
373369374370 # Likelihood of the actual realization.
375371 y_data = numpyro.sample('y_obs', dist.Normal(loc=yhat, scale=sigma), obs=data[1:])
@@ -379,15 +375,13 @@ def AR1_model_y0(data):
379375```{code-cell} ipython3
380376:tag: [hide-output]
381377382-# make jnp array
378+# Make jnp array
383379y = jnp.array(y)
384380385-# set NUTS kernal
381+# Set NUTS kernal
386382NUTS_kernel = numpyro.infer.NUTS(AR1_model_y0)
387383388-# run MCMC
389-390-384+# Run MCMC
391385mcmc2 = numpyro.infer.MCMC(NUTS_kernel, num_samples=50000, num_warmup=10000, progress_bar=False)
392386mcmc2.run(rng_key=random.PRNGKey(1), data=y)
393387```
@@ -402,10 +396,10 @@ mcmc2.print_summary()
402396403397Look what happened to the posterior!
404398405-It has moved far from the true values of the parameters used to generate the data because of how Bayes Law (i.e., conditional probability)
406-is telling `numpyro` to explain what it interprets as "explosive" observations early in the sample
399+It has moved far from the true values of the parameters used to generate the data because of how Bayes' Law (i.e., conditional probability)
400+is telling `numpyro` to explain what it interprets as "explosive" observations early in the sample.
407401408-Bayes Law is able to generates a plausible likelihood for the first observation is by driving $\rho \rightarrow 1$ and $\sigma \uparrow$ in order to raise the variance of the stationary distribution.
402+Bayes' Law is able to generate a plausible likelihood for the first observation by driving $\rho \rightarrow 1$ and $\sigma \uparrow$ in order to raise the variance of the stationary distribution.
409403410-Our example illustrates the importance of what you assume about the distribution of initial conditions.
404+Our example illustrates the importance of what you assume about the distribution of initial conditions.
411405