Hypergeometric Distribution
Probability Distributions
Sampling Without Replacement — Finite Populations
The hypergeometric distribution models the number of successes when sampling without replacement from a finite population. Every draw changes the odds.
- Card games — probability of drawing aces in a poker hand
- Quality inspection — defective items in a batch sample
- Ecology — capture-recapture population estimation
- Legal sampling — random drug testing from a workforce
Unlike the binomial, the hypergeometric accounts for the fact that each draw depletes the population.
Core Concepts
The hypergeometric distribution models the number of successes when sampling without replacement from a finite population. It is the correct distribution for card games, quality inspection of small batches, and any scenario where the population is depleted as items are drawn.
Mean and Variance
The Finite Population Correction Factor
Convergence to Binomial
Symmetry Property
Worked Example: Lottery / Card Draw
Python Implementation
import numpy as np
from scipy import stats
np.random.seed(42)
# Hypergeometric parameters
N, K, n = 52, 4, 5 # deck, aces, draws
# Theoretical mean and variance
mean_theory = n * K / N
var_theory = n * (K/N) * (1 - K/N) * (N - n) / (N - 1)
print(f"Hyp({N}, {K}, {n}):")
print(f" Theoretical mean: {mean_theory:.4f}")
print(f" Theoretical variance: {var_theory:.4f}")
# Simulate
n_sims = 100000
samples = np.random.hypergeometric(K, N - K, n, size=n_sims)
print(f" Empirical mean: {np.mean(samples):.4f}")
print(f" Empirical variance: {np.var(samples, ddof=0):.4f}")
# Compare with binomial (with replacement)
binom_var = n * (K/N) * (1 - K/N)
fpc = (N - n) / (N - 1)
print(f"\n Binomial variance (with replacement): {binom_var:.4f}")
print(f" Finite population correction: {fpc:.4f}")
print(f" Hyp var / Bin var = {var_theory / binom_var:.4f} (should be {fpc:.4f})")
Python Implementation: Batch Quality Inspection
import numpy as np
from scipy import stats
np.random.seed(42)
# Quality control: batch of 100 items, 8 defective, sample 10
N, K, n = 100, 8, 10
samples = np.random.hypergeometric(K, N - K, n, size=50000)
print(f"Quality Inspection: N={N}, K={K} defective, sample n={n}")
print(f"PMF values:")
for k in range(min(n, K) + 1):
pmf = stats.hypergeom.pmf(k, N, K, n)
print(f" P(X={k}) = {pmf:.4f}")
print(f"\nSimulated mean: {np.mean(samples):.4f} (theoretical: {n*K/N:.4f})")
# Probability of finding at least 2 defectives
prob_ge_2 = 1 - stats.hypergeom.cdf(1, N, K, n)
print(f"P(X >= 2 defectives in sample) = {prob_ge_2:.4f}")