Contents
Deep Breakdown
What it tells me (Situation Awareness): The PMF assigns a probability to each specific value that a discrete random variable can take. It is the complete specification of a discrete distribution. In DA/DS: used for Bernoulli, Binomial, Poisson, and Negative Binomial distributions that model counts, binary outcomes, and rare events.
Flowchart
Real-world use
Where it is used
Modeling the number of support tickets per day (Poisson), probability of conversion (Bernoulli), number of successes in trials (Binomial), or count data in general.
Problem it solves
Provides an exact probability for each discrete outcome — unlike continuous distributions where .
How it solves the problem
Maps each possible discrete value to a non-negative probability, where all probabilities sum to 1.
Example in a business
A/B test with 1000 users: . . Used to assess how likely exactly 50 conversions are under the null.
The formula, piece by piece
- : the PMF at value .
- : probability that the random variable equals exactly .
- Must satisfy: for all , and .
The formula in words
"The PMF at equals the probability that the random variable takes exactly the value ."
Critical Concepts
- Discrete only: PMF assigns exact probabilities. CRVs use PDF instead.
- CDF from PMF: .
- PMF bar chart: each bar height = exact probability.
- Python:
scipy.stats.<dist>.pmf(k, ...).
Step-by-step calculation (tiny example)
Step 1: Fair die = outcome of a fair 6-sided die. for .
Step 2: Verify . Valid PMF.
Step 3: Query .
Code examples
Beginner example (Python)
from scipy.stats import binom # PMF for Binomial: n=10 trials, p=0.3 success rate
n_trials = 10
p_success = 0.3
k_values = range(n_trials + 1)
pmf_values = [binom.pmf(k, n_trials, p_success) for k in k_values]
print(f"{'k':>4} {'P(X=k)':>10}")
for k, p in zip(k_values, pmf_values):
print(f"{k:>4} {p:>10.6f}")Beginner example (R)
n_trials <- 10; p_success <- 0.3
k_values <- 0:n_trials
pmf_values <- dbinom(k_values, n_trials, p_success)
for (i in seq_along(k_values)) { cat(sprintf("P(X=%2d) = %.6f\n", k_values[i], pmf_values[i]))
}Professional example (Python)
import numpy as np
from scipy.stats import binom, poisson
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
def compare_pmfs( n_trials: int, p_success: float, lambda_rate: float | None = None ) -> dict[str, np.ndarray]:
"""Compare Binomial and Poisson PMFs for count modeling. When lambda = n*p (large n, small p), Poisson approximates Binomial. Args: n_trials: Binomial n parameter. p_success: Binomial p parameter. lambda_rate: Poisson lambda (defaults to n*p). Returns: Dict with k values and PMFs for both distributions. """
lam = lambda_rate if lambda_rate is not None else n_trials * p_success
k_range = np.arange(0, min(int(lam * 5) + 1, n_trials + 1))
return { "k": k_range, "binomial_pmf": binom.pmf(k_range, n_trials, p_success), "poisson_pmf": poisson.pmf(k_range, lam), "lambda": lam, }
result = compare_pmfs(n_trials=100, p_success=0.05)
print(f"Binomial(100, 0.05) vs Poisson(lambda={result['lambda']}):")
print(f"{'k':>4} {'Binom PMF':>12} {'Poisson PMF':>13} {'Abs diff':>10}")
for k, b_pmf, p_pmf in zip(result["k"][:10], result["binomial_pmf"][:10], result["poisson_pmf"][:10]):
print(f"{k:>4} {b_pmf:>12.6f} {p_pmf:>13.6f} {abs(b_pmf - p_pmf):>10.6f}")Source: AIO p. 85