GitHub

@@ -141,12 +141,7 @@ from numpyro.infer import MCMC, NUTS

141141

import jax.numpy as jnp

142142

from jax import random

143143144-

np.random.seed(142857)

145-146-

@jit

147-

def set_seed():

148-

np.random.seed(142857)

149-

set_seed()

144+

rng = np.random.default_rng(142857)

150145

```

151146152147

Let's use Python to generate two beta distributions

@@ -172,7 +167,7 @@ g = jit(lambda x: p(x, G_a, G_b))

172167

:hide-output: false

173168174169

@jit

175-

def simulate(a, b, T=50, N=500):

170+

def simulate(a, b, rng, T=50, N=500):

176171

'''

177172

Generate N sets of T observations of the likelihood ratio,

178173

return as N x T matrix.

@@ -184,7 +179,7 @@ def simulate(a, b, T=50, N=500):

184179

for i in range(N):

185180186181

for j in range(T):

187-

w = np.random.beta(a, b)

182+

w = rng.beta(a, b)

188183

l_arr[i, j] = f(w) / g(w)

189184190185

return l_arr

@@ -195,14 +190,14 @@ We’ll also use the following Python code to prepare some informative simulatio

195190

```{code-cell} ipython3

196191

:hide-output: false

197192198-

l_arr_g = simulate(G_a, G_b, N=50000)

193+

l_arr_g = simulate(G_a, G_b, rng, N=50000)

199194

l_seq_g = np.cumprod(l_arr_g, axis=1)

200195

```

201196202197

```{code-cell} ipython3

203198

:hide-output: false

204199205-

l_arr_f = simulate(F_a, F_b, N=50000)

200+

l_arr_f = simulate(F_a, F_b, rng, N=50000)

206201

l_seq_f = np.cumprod(l_arr_f, axis=1)

207202

```

208203

@@ -217,7 +212,7 @@ Here is pseudo code for a direct "method 1" for drawing from our compound lotter

217212218213

* Step one:

219214220-

* use the numpy.random.choice function to flip an unfair coin that selects distribution $F$ with prob $\alpha$

215+

* use the `rng.choice` method to flip an unfair coin that selects distribution $F$ with prob $\alpha$

221216

and $G$ with prob $1 -\alpha$

222217223218

* Step two:

@@ -251,24 +246,24 @@ from our target mixture distribution.

251246252247

```{code-cell} ipython3

253248

@jit

254-

def draw_lottery(p, N):

249+

def draw_lottery(p, rng, N):

255250

"Draw from the compound lottery directly."

256251257252

draws = []

258253

for i in range(0, N):

259-

if np.random.rand()<=p:

260-

draws.append(np.random.beta(F_a, F_b))

254+

if rng.random()<=p:

255+

draws.append(rng.beta(F_a, F_b))

261256

else:

262-

draws.append(np.random.beta(G_a, G_b))

257+

draws.append(rng.beta(G_a, G_b))

263258

return np.array(draws)

264259265-

def draw_lottery_MC(p, N):

260+

def draw_lottery_MC(p, rng, N):

266261

"Draw from the compound lottery using the Monte Carlo trick."

267262268263

xs = np.linspace(1e-8,1-(1e-8),10000)

269264

CDF = p*sp.beta.cdf(xs, F_a, F_b) + (1-p)*sp.beta.cdf(xs, G_a, G_b)

270265271-

Us = np.random.rand(N)

266+

Us = rng.random(N)

272267

draws = xs[np.searchsorted(CDF[:-1], Us)]

273268

return draws

274269

```

@@ -278,8 +273,8 @@ def draw_lottery_MC(p, N):

278273

N = 100000

279274

α = 0.0

280275281-

sample1 = draw_lottery(α, N)

282-

sample2 = draw_lottery_MC(α, N)

276+

sample1 = draw_lottery(α, rng, N)

277+

sample2 = draw_lottery_MC(α, rng, N)

283278284279

# plot draws and density function

285280

plt.hist(sample1, 50, density=True, alpha=0.5, label='direct draws')

@@ -409,24 +404,24 @@ what fundamental force determines the limiting value of $\pi_t$.

409404

Let's set a value of $\alpha$ and then watch how $\pi_t$ evolves.

410405411406

```{code-cell} ipython3

412-

def simulate_mixed(α, T=50, N=500):

407+

def simulate_mixed(α, rng, T=50, N=500):

413408

"""

414409

Generate N sets of T observations of the likelihood ratio,

415410

return as N x T matrix, when the true density is mixed h;α

416411

"""

417412418-

w_s = draw_lottery(α, N*T).reshape(N, T)

413+

w_s = draw_lottery(α, rng, N*T).reshape(N, T)

419414

l_arr = f(w_s) / g(w_s)

420415421416

return l_arr

422417423-

def plot_π_seq(α, π1=0.2, π2=0.8, T=200):

418+

def plot_π_seq(α, rng, π1=0.2, π2=0.8, T=200):

424419

"""

425420

Compute and plot π_seq and the log likelihood ratio process

426421

when the mixed distribution governs the data.

427422

"""

428423429-

l_arr_mixed = simulate_mixed(α, T=T, N=50)

424+

l_arr_mixed = simulate_mixed(α, rng, T=T, N=50)

430425

l_seq_mixed = np.cumprod(l_arr_mixed, axis=1)

431426432427

T = l_arr_mixed.shape[1]

@@ -456,7 +451,7 @@ def plot_π_seq(α, π1=0.2, π2=0.8, T=200):

456451

```

457452458453

```{code-cell} ipython3

459-

plot_π_seq(α = 0.6)

454+

plot_π_seq(α = 0.6, rng=rng)

460455

```

461456462457

The above graph shows a sample path of the log likelihood ratio process as the blue dotted line, together with

@@ -466,7 +461,7 @@ sample paths of $\pi_t$ that start from two distinct initial conditions.

466461

Let's see what happens when we change $\alpha$

467462468463

```{code-cell} ipython3

469-

plot_π_seq(α = 0.2)

464+

plot_π_seq(α = 0.2, rng=rng)

470465

```

471466472467

Evidently, $\alpha$ is having a big effect on the destination of $\pi_t$ as $t \rightarrow + \infty$

@@ -541,7 +536,7 @@ def π_lim(α, T=5000, π_0=0.4):

541536

"Find limit of π sequence."

542537

π_seq = np.zeros(T+1)

543538

π_seq[0] = π_0

544-

l_arr = simulate_mixed(α, T, N=1)[0]

539+

l_arr = simulate_mixed(α, rng, T, N=1)[0]

545540546541

for t in range(T):

547542

π_seq[t+1] = update(π_seq[t], l_arr[t])

@@ -661,7 +656,7 @@ We use the `Mixture` class in numpyro to construct the likelihood function.

661656

α = 0.8

662657663658

# simulate data with true α

664-

data = draw_lottery(α, 1000)

659+

data = draw_lottery(α, rng, 1000)

665660

sizes = [5, 20, 50, 200, 1000, 25000]

666661667662

def model(w):

@@ -785,7 +780,7 @@ T_mix = 200

785780

prior_params = [(1, 3), (1, 1), (3, 1)]

786781

prior_means = [a/(a+b) for a, b in prior_params]

787782788-

w_mix = draw_lottery(x_true, T_mix)

783+

w_mix = draw_lottery(x_true, rng, T_mix)

789784

```

790785791786

```{code-cell} ipython3

@@ -849,14 +844,14 @@ The plot shows that regardless of the initial prior belief, all three posterior

849844

Next, let's look at multiple simulations with a longer time horizon, all starting from a uniform prior.

850845851846

```{code-cell} ipython3

852-

set_seed()

847+

rng = np.random.default_rng(142857)

853848

n_paths = 20

854849

T_long = 10_000

855850856851

fig, ax = plt.subplots(figsize=(10, 5))

857852858853

for j in range(n_paths):

859-

w_path = draw_lottery(x_true, T_long)

854+

w_path = draw_lottery(x_true, rng, T_long)

860855

x_means = learn_x_bayesian(w_path, 1, 1) # Uniform prior

861856

ax.plot(range(T_long + 1), x_means, alpha=0.5, linewidth=1)

862857

Read the original on github.com ↗