Skip to content

Commit 37daf78

Browse files
Update rng usage in mix_model.md (#978)
1 parent 6f473fe commit 37daf78

1 file changed

Lines changed: 25 additions & 30 deletions

File tree

lectures/mix_model.md

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,7 @@ from numpyro.infer import MCMC, NUTS
141141
import jax.numpy as jnp
142142
from jax import random
143143
144-
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
```
151146

152147
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
173168
174169
@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):
185180
186181
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)
189184
190185
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
197192
198-
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
```
201196

202197
```{code-cell} ipython3
203198
:hide-output: false
204199
205-
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
217212

218213
* Step one:
219214

220-
* 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$
222217

223218
* Step two:
@@ -251,24 +246,24 @@ from our target mixture distribution.
251246

252247
```{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."
256251
257252
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)
264259
265-
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."
267262
268263
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)
270265
271-
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
280275
281-
sample1 = draw_lottery(α, N)
282-
sample2 = draw_lottery_MC(α, N)
276+
sample1 = draw_lottery(α, rng, N)
277+
sample2 = draw_lottery_MC(α, rng, N)
283278
284279
# 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.
410405
411406
```{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
"""
417412
418-
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)
420415
421416
return l_arr
422417
423-
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
"""
428423
429-
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)
431426
432427
T = l_arr_mixed.shape[1]
@@ -456,7 +451,7 @@ def plot_π_seq(α, π1=0.2, π2=0.8, T=200):
456451
```
457452
458453
```{code-cell} ipython3
459-
plot_π_seq(α = 0.6)
454+
plot_π_seq(α = 0.6, rng=rng)
460455
```
461456
462457
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$
467462
468463
```{code-cell} ipython3
469-
plot_π_seq(α = 0.2)
464+
plot_π_seq(α = 0.2, rng=rng)
470465
```
471466
472467
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]
545540
546541
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
662657
663658
# simulate data with true α
664-
data = draw_lottery(α, 1000)
659+
data = draw_lottery(α, rng, 1000)
665660
sizes = [5, 20, 50, 200, 1000, 25000]
666661
667662
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]
787782
788-
w_mix = draw_lottery(x_true, T_mix)
783+
w_mix = draw_lottery(x_true, rng, T_mix)
789784
```
790785

791786
```{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.
850845

851846
```{code-cell} ipython3
852-
set_seed()
847+
rng = np.random.default_rng(142857)
853848
n_paths = 20
854849
T_long = 10_000
855850
856851
fig, ax = plt.subplots(figsize=(10, 5))
857852
858853
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

0 commit comments

Comments
 (0)