Session 2: data, seeds and reproducibility#
Zoo models: Boltzmann wealth exchange, Bouchaud-Mezard
Goals#
Collect model-level data with a
DataCollectorand turn it into a pandas DataFrame.Understand why every draw must come from
model.rngormodel.random, and check that the same seed gives the same run.Tell apart a transient from a stationary state, and average only the latter.
Before the session: the collecting data tutorial and Checking a model.
Exercises#
2.1 Run Bouchaud-Mezard twice with rng=7 and once with rng=8. Show that the first
two Gini series are identical and the third is not.
Solution
from modelly.zoo.bouchaud_mezard.model import BouchaudMezard, BouchaudMezardScenario
def gini_series(seed):
model = BouchaudMezard(BouchaudMezardScenario(rng=seed, steps=300))
model.run()
return model.datacollector.get_model_vars_dataframe()["gini"]
print(gini_series(7).equals(gini_series(7)), gini_series(7).equals(gini_series(8)))
2.2 Replace self.rng.standard_normal(...) in a copy of the model by
numpy.random.standard_normal(...). Run modelly lint on the copy. What does it report,
and why does it matter?
Solution
MDL001 random draw outside the model's generators. The global numpy generator is not
seeded by the scenario, so two runs with the same seed differ, and runs in worker processes
may even share a stream.
2.3 Plot the Gini of the Boltzmann exchange over time. How many steps does it take to
settle? Estimate its stationary mean from the second half only, and compare with
model.stationary_gini().
Solution
from modelly.zoo.kinetic_wealth.model import KineticScenario, KineticWealth
model = KineticWealth(KineticScenario(rng=3, steps=1000))
model.run()
series = model.datacollector.get_model_vars_dataframe().iloc[:, 0]
series.plot()
print(series.iloc[500:].mean(), model.stationary_gini())
The Gini rises for a few hundred steps, then fluctuates around the exact value.
2.4 Save the Bouchaud-Mezard model halfway with model.save(path), load it with
BouchaudMezard.load(path) and run both to the end. Are the final wealth vectors equal?
Solution
Yes, element for element: a checkpoint holds the state of both generators, so the resumed run draws exactly the same numbers. See Checkpoints.