The Poisson distribution models the number of events in a fixed interval of time or space. Use it for nonnegative integer counts when events occur independently at a constant average rate. Possible applications include hourly calls, daily absences, and defects per unit; check that the assumptions suit the situation before interpreting the probabilities. section 3.1.4 section 9.3.1
Its single parameter, λ, is the average count per interval. For a count k, the probability mass function is P(X = k) = e^(−λ)λ^k/k!. Both the mean and variance equal λ. At lower rates the distribution is right-skewed; as the rate increases, its shape approaches a normal distribution. section 3.1.4
Calculate a count probability
If the average is two events per interval, the probability of exactly four is about 9.02%. The formula and SciPy give the same result: import math import numpy as np from scipy.stats import poisson lam, k = 2, 4 p_formula = np.exp(-lam) * lam**k / math.factorial(k) p_scipy = poisson.pmf(k, lam) print(p_formula, p_scipy) # approximately 0.09022, 0.09022 section 3.1.4
>>> import numpy as np #1
>>> import pandas as pd #2
>>> from scipy.stats import poisson #3
>>> lam = 2 #4
>>> k_values = np.arange(0, 9) #5
>>> probabilities = poisson.pmf(k_values, lam) #6
>>> probabilities_percentage = \
>>> np.round(probabilities * 100, 2) #7
>>> poisson_table = pd.DataFrame({'k': k_values, \
>>> 'Probability (%)': probabilities_percentage}) #8
>>> print(poisson_table) #9
k Probability (%)
0 0 13.53
1 1 27.07
2 2 27.07
3 3 18.04
4 4 9.02
5 5 3.61
6 6 1.20
7 7 0.34
8 8 0.09
For a call center averaging two absences per day, this table calculates probabilities for zero through eight absentees. Zero has probability 13.53%; one and two each have probability 27.07%. It makes the staffing risk behind the average visible. section 9.3.1
The probabilities can also drive a Monte Carlo staffing simulation. In the illustrated setup, 500 draws use a fixed random seed and probabilities for counts zero through eight. Those probabilities are normalized because higher counts were omitted; the resulting draws therefore use a truncated, renormalized set of outcomes rather than the full Poisson distribution. Small differences between simulated frequencies and theoretical probabilities are expected from random sampling, not proof that the underlying probabilities changed. section 9.4 section 9.4.1
>>> np.random.seed(0) #1
>>> units = 20 #2
>>> defects = np.random.poisson(lam = 4,
>>> size = units) #3
>>> c_bar = np.mean(defects) #4
>>> UCL = c_bar + 3 * np.sqrt(c_bar) #5
>>> LCL = max(0, c_bar - 3 * np.sqrt(c_bar)) #6
>>> plt.figure() #7
>>> plt.plot(range(1, units + 1), defects,
>>> marker = 'o', linestyle = '-', color = 'b',
>>> label = 'Number of Defects') #8
>>> plt.axhline(c_bar,
>>> color = 'r', linestyle = '--',
>>> label = 'Center Line') #9
>>> plt.axhline(UCL,
>>> color = 'g', linestyle = '--',
>>> label = 'UCL') #10
>>> plt.axhline(LCL,
>>> color = 'g', linestyle = '--',
>>> label = 'LCL') #11
>>> plt.title('c-Chart')
>>> plt.xlabel('Unit Number')
>>> plt.ylabel('Number of Defects')
>>> plt.xticks(range(1, units + 1))
>>> plt.legend(loc = 'upper right',
>>> bbox_to_anchor = (1, .95))
>>> plt.grid(True)
>>> plt.show() #12
A quality-control example generates defect counts for 20 units with `np.random.poisson(lam=4, size=units)`, then plots a c-chart. Its center line uses the observed mean; control limits use that mean plus or minus three times its square root, with the lower limit bounded at zero. The plotted counts stay within the limits. section 14.2.3






