liveBook · Manning

Monte Carlo simulation

As explained in Statistics Every Programmer Needs

A Monte Carlo simulation estimates quantities or evaluates outcomes by repeatedly sampling from specified probability distributions or stochastic processes.

Monte Carlo simulation repeatedly samples uncertain inputs to produce a distribution of possible outcomes. Instead of one fixed forecast, it shows how often different results occur. It is useful when interacting variables or nonlinear relationships make an exact solution impractical, and when a decision depends on risk as well as the average outcome. section 9.0 section 9.1

A practical workflow is:

  • Define uncertain inputs and their distributions using historical data, domain knowledge, or explicit assumptions. Check that the chosen distributions fit the quantities being modeled. section 9.2
  • Generate outcomes. For discrete values, cumulative probabilities can map random numbers to outcomes. For continuous stock returns, estimated parameters can drive draws from a normal distribution. section 9.2 section 9.5.1
  • Repeat the trial, count or plot the results, and compare decisions against the resulting variability—not just the mean. Use enough trials to avoid leaning on an anomalous small sample. section 9.3.5 section 9.3.6

Staffing for absenteeism

Suppose a call center’s daily absentee count follows a Poisson distribution with an estimated rate of two. Ten simulated days produce a mean of 2.4 absences, while the calculated expected value is about 2. That difference is not evidence that the rate has changed: ten draws can be unrepresentative. A manager can weigh extra payroll against the service risk of having too few staff; 500 automated trials give a clearer view of the modeled distribution. section 9.3.1 section 9.3.6 section 9.4

>>> np.random.seed(1)     #1
>>> num_trials = 500     #2
>>> normalized_probabilities = \
>>>     probabilities / probabilities.sum()    #3
>>> simulated_values = np.random.choice(k_values,     #4
>>>                      size = num_trials,     #5
>>>                      p = normalized_probabilities)     #6
>>> unique, counts = \
>>>     np.unique(simulated_values,     #7
>>>                 return_counts = True)   #8
>>> simulated_counts = \
>>>     dict(zip(unique, counts))       #9
>>> simulated_percentages = \
>>>     {k: (v / num_trials) * 100 for k, \
>>>     v in simulated_counts.items()}     #10

The Python implementation seeds the random generator, normalizes probabilities over the included absentee counts, draws 500 values with NumPy, and tabulates their frequencies. Normalization matters because higher counts were omitted from the displayed set. section 9.4

For stock prices, historical closing prices instead supply daily log returns. Their estimated mean and standard deviation parameterize simulated daily returns, producing a range of potential price paths rather than a single forecast. Such results remain conditional on the historical data and the assumed return distribution. section 9.5.1 section 1.4.2

How Statistics Every Programmer Needs covers it

How deep it goes
Develops a six-step discrete workflow and a historical-return-based continuous workflow, including sampling and interpretation.
Examples
Uses Poisson-modeled call-center absenteeism and historical stock prices as discrete and continuous examples.
What it assumes
Builds on introductory probability and random variables while introducing Python code progressively.
What you can do after
Build it from scratch in Python, then compare simulated frequencies and decision tradeoffs.
How it connects
Connects probability distributions, cumulative distribution functions, random variables, log returns, and normal distributions to simulation.

Also explained in

Compare how 8 books explain Monte Carlo simulation →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Statistics Every Programmer Needs. The section links point to the parts of the book it draws on.