7  Poisson — The Limit of Many Rare Events

7.1 An applied scenario — bearing faults per hour

A different sensor on the motor monitors shock pulses — the high-frequency clicks a damaged ball bearing emits as it rolls past a load zone. On a healthy bearing, these clicks are extremely rare; on a damaged one, they multiply.

You want a maintenance metric: how many shock pulses arrive in a one-hour window?

Try modelling this with the Binomial. You’d need:

  • n — the number of “trials” per hour. But what is a trial? A nanosecond? A bearing rotation? It depends on how finely you slice time.
  • p — the probability of a click in one trial. As you slice time finer, n grows and p shrinks.

Yet the expected count per hour — say, \lambda = 3 clicks/hour on a healthy bearing — is a real, measurable physical quantity. It doesn’t depend on how you slice time.

You want a distribution parameterised by \lambda alone, where the trial-counting machinery quietly disappears. That distribution exists, and it’s what the Binomial becomes in exactly this regime.


7.2 Intuition

The Poisson distribution is what the Binomial becomes when:

  • n \to \infty (the region is sliced into infinitely many trials)
  • p \to 0 (each trial is vanishingly unlikely)
  • \lambda = np stays constant (the expected count is fixed by the physics)

The two parameters collapse into one: \lambda, the expected count per region.


7.3 The derivation

Start from the Binomial PMF and substitute p = \lambda / n:

P(k) \;=\; \binom{n}{k} \left(\frac{\lambda}{n}\right)^k \left(1 - \frac{\lambda}{n}\right)^{n - k}

For large n:

\binom{n}{k} \;=\; \frac{n(n-1)\cdots(n-k+1)}{k!} \;\approx\; \frac{n^k}{k!}

Substitute back. The n^k terms cancel:

P(k) \;\approx\; \frac{\lambda^k}{k!} \left(1 - \frac{\lambda}{n}\right)^{n} \left(1 - \frac{\lambda}{n}\right)^{-k}

As n \to \infty, (1 - \lambda/n)^n \to e^{-\lambda} and (1 - \lambda/n)^{-k} \to 1, leaving

P(k \mid \lambda) \;=\; \frac{\lambda^k \, e^{-\lambda}}{k!}

\boxed{P(k \mid \lambda) \;=\; \frac{\lambda^k \, e^{-\lambda}}{k!}}

Mean: E[k] = \lambda

Variance: \operatorname{Var}(k) = \lambda

The magical property: mean equals variance. This single fact is the engine behind every shot-noise calculation in sensors, every queueing model in networks, and every count-based regression in statistics.


7.4 The Poisson has ONE parameter

Distribution Parameters Mean Variance Mean = Variance?
Binomial(n, p) n, p np np(1-p) only when p \to 0
Poisson(\lambda) \lambda \lambda \lambda always

If you measure the mean of a Poisson process, you immediately know its variance.


7.5 Examples across domains

Process Underlying n Underlying p \lambda
Bearing shock pulses Time slices per hour P(click in slice) Clicks per hour
Network packet drops Packets per minute P(drop) Drops per minute
Photon counting Available photons P(photon hits photosite) Expected electrons per exposure
Defects on a surface Surface micro-cells P(defect per cell) Defects per m²
Earthquakes in a region “Trial” stress events P(release per event) Events per year

Huge n, tiny p, moderate \lambda — the Poisson regime.


7.6 Watching Binomial → Poisson

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import binom, poisson

np.random.seed(42)

lambda_fixed = 20

fig, axes = plt.subplots(2, 3, figsize=(15, 8))
n_values = [20, 50, 100, 500, 2000, 10000]

for ax, n in zip(axes.flat, n_values):
    p = lambda_fixed / n   # p shrinks as n grows; np = λ stays constant

    k = np.arange(max(0, int(lambda_fixed - 4 * np.sqrt(lambda_fixed))),
                  int(lambda_fixed + 4 * np.sqrt(lambda_fixed)) + 1)
    binom_pmf = binom.pmf(k, n, p)
    pois_pmf  = poisson.pmf(k, lambda_fixed)

    ax.bar(k - 0.15, binom_pmf, width=0.3, color="#2196F3", alpha=0.8,
           label=f"Binomial(n={n})")
    ax.bar(k + 0.15, pois_pmf,  width=0.3, color="#F44336", alpha=0.8,
           label=f"Poisson(λ={lambda_fixed})")
    max_diff = np.max(np.abs(binom_pmf - pois_pmf))
    ax.set_title(f"n = {n},  max |diff| = {max_diff:.2e}")
    ax.set_xlabel("k")
    ax.set_ylabel("P(k)")
    ax.legend(fontsize=7)

plt.suptitle(f"Binomial → Poisson (λ = np = {lambda_fixed} fixed)",
             fontsize=13)
plt.tight_layout()
plt.show()

By n \approx 100, the difference is already negligible. By n = 10\,000, the two distributions are indistinguishable.


7.7 Back to the bearing

For the healthy bearing with \lambda = 3 clicks/hour:

lam = 3
print(f"Expected count       : {lam}")
print(f"Standard deviation   : {np.sqrt(lam):.3f}")
print(f"P(0 clicks)          : {poisson.pmf(0, lam):.4f}")
print(f"P(>= 10 clicks)      : {1 - poisson.cdf(9, lam):.6f}")
Expected count       : 3
Standard deviation   : 1.732
P(0 clicks)          : 0.0498
P(>= 10 clicks)      : 0.001102

So observing 0 clicks in an hour is uncommon (5 % of healthy hours) but not alarming. Observing 10 clicks in an hour is roughly a 1-in-1000 event under the healthy model — strong evidence the bearing state has changed.


7.8 Poisson noise along a gradient

The variance-equals-mean property has a direct consequence for sensors: in a brightness gradient, dark pixels are relatively noisier than bright pixels.

np.random.seed(0)

pixel_positions = np.arange(200)
expected_photons = 5 + 195 * (pixel_positions / 199)   # λ from 5 to 200

fig, axes = plt.subplots(3, 1, figsize=(12, 8))

axes[0].plot(pixel_positions, expected_photons, "k-", linewidth=2)
axes[0].fill_between(pixel_positions, expected_photons, alpha=0.1, color="black")
axes[0].set_ylabel("Expected photons (λ)")
axes[0].set_title("True scene (no noise)")

one_capture = np.random.poisson(expected_photons.astype(int))
axes[1].bar(pixel_positions, one_capture, width=1, color="#2196F3", alpha=0.7)
axes[1].plot(pixel_positions, expected_photons, "k--", linewidth=1.5,
             label="True signal")
axes[1].set_ylabel("Detected photons")
axes[1].set_title("One exposure — Poisson noise")
axes[1].legend()

many = np.random.poisson(expected_photons.astype(int), size=(1000, 200))
measured = many.std(axis=0)
theory = np.sqrt(expected_photons)

axes[2].plot(pixel_positions, measured, color="#2196F3", linewidth=1.5,
             label="Measured std (1 000 captures)")
axes[2].plot(pixel_positions, theory, "k--", linewidth=2, label="Theory √λ")
axes[2].set_xlabel("Pixel position")
axes[2].set_ylabel("Noise (std dev)")
axes[2].set_title("σ = √λ — the Poisson signature")
axes[2].legend()

plt.tight_layout()
plt.show()

Top: noiseless ground truth. Middle: one Poisson capture (more visible noise on the dark left). Bottom: measured std exactly tracks σ = √λ.

Dark pixels (left, \lambda \approx 5) have noise \sigma \approx \sqrt 5 \approx 2.2 — relative noise \approx 45 \%. Bright pixels (right, \lambda \approx 200) have \sigma \approx 14.1 — relative noise \approx 7 \%. Noise grows in absolute terms but shrinks relative to signal: SNR = \sqrt{\lambda}.


7.9 Why Poisson is the right model for photon counting

A typical LED emits ~10^{18} photons per second. The probability that any specific photon reaches a 6 µm × 6 µm photosite is vanishingly small. But the product \lambda = np — determined by illumination, reflectance, exposure time, and sensor area — sits in the range of tens to thousands.

This is exactly the Poisson regime: enormous n, tiny p, moderate \lambda. The Poisson model is not an approximation here — it is the physically correct distribution for photon counting.


7.10 Exercises

  1. For \lambda = 20, plot Binomial(n, \lambda/n) vs Poisson PMFs at n = 50, 100, 1000. Plot max |\Delta| vs n on a log-log scale.
  2. For \lambda \in \{1, 5, 10, 50, 200\} verify by simulation that \sigma \approx \sqrt{\lambda}.
  3. The Anscombe transform f(x) = 2\sqrt{x + 3/8} stabilises Poisson variance. Simulate Poisson data at \lambda \in \{5, 50, 500\}, apply the transform, and confirm the post-transform std is approximately 1 across all three.

7.11 Glossary

Poisson distribution — count of rare independent events; P(k) = \lambda^k e^{-\lambda}/k!.

\lambda — expected count per region.

shot noise — the Poisson noise in photon-counting (or any similar) processes.

variance equals mean — the Poisson signature.