Contents
, with CDF on , mean and variance
Deep Breakdown
What it tells me (Situation Awareness): The continuous Uniform distribution says every value in the interval is equally likely, so the density is a flat rectangle of height and the probability of any sub-interval is simply its length divided by the total length. It is the mathematical form of "I only know the bounds". It is also the raw material of simulation: computers generate numbers, and the inverse-CDF trick turns them into draws from any other distribution. A less obvious but very practical fact: when the null hypothesis is true and the test is valid, p-values follow , which is how I audit an experimentation platform with A/A tests. In DA/DS: random search over hyperparameters, weight initialisation in neural networks, Monte Carlo simulation, random traffic assignment (hash a user ID into and compare to the split), bounded "non-informative" priors, jitter in plots, and p-value calibration checks.
Flowchart
Real-world use
Where it is used
Monte Carlo simulation and inverse-transform sampling, random search and Bayesian optimisation bounds for hyperparameters, Xavier/Glorot uniform weight initialisation, random assignment in A/B testing, scenario analysis when only a min and max are known (lead time, price range), and checking that p-values under a true null are uniform.
Problem it solves
Provides the simplest valid model when every value in a range is equally plausible, and a neutral source of randomness from which all other random variables can be built.
How it solves the problem
Spreads total probability 1 evenly over : height times width gives area 1. Any question about the probability of a range becomes a ratio of lengths, and the linear CDF is trivially invertible, so turns a standard uniform into any .
Example in a business
A supplier promises delivery "between 2 and 10 days" with no further information, so I model lead time as . The chance a parcel arrives between day 3 and day 5 is . Expected lead time is days with variance (standard deviation days). For a promise date that 90% of orders meet, I take the 90th percentile days.
The formula, piece by piece
- : continuous random variable restricted to .
- , : lower and upper bounds, with .
- : width of the support.
- : constant density height; it is not a probability, it makes the total area equal 1.
- : share of the interval lying below .
- : the midpoint.
- : depends only on the width.
- Quantile: .
The formula in words
"Every point between and is equally likely, so the probability of landing in a sub-range is that sub-range's length divided by the whole length." Tiny example: a promo code is redeemed uniformly over a 60-minute flash sale. .
Critical Concepts
- Density is not probability: can exceed 1 when the interval is shorter than 1 (e.g. has height 2). Only areas are probabilities, and for any single point.
- Inverse transform sampling: if and is a CDF, then has CDF . For example is Exponential with rate .
- Probability integral transform: the reverse, , explains why valid p-values are uniform under the null and underpins PIT calibration checks for forecasts.
- Max-entropy: among all distributions on a bounded interval, the Uniform has the highest entropy, which is why it is the default "know only the bounds" choice.
- Log-uniform for scales: for hyperparameters such as the learning rate, sample uniformly (e.g. from to ), not the learning rate itself, so each order of magnitude gets equal attention.
- Discrete cousin: a fair die is the discrete Uniform on , with variance instead of .
Step-by-step calculation (tiny example)
Step 1: Set up Lead time , width , density .
Step 2: Interval probability .
Step 3: Mean .
Step 4: Variance and standard deviation , .
Step 5: 90th percentile days.
Code examples
Beginner example (Python)
from scipy.stats import uniform
a, b = 2, 10
dist = uniform(loc=a, scale=b - a) # scipy uses loc=a, scale=b-a
print(f"Density height = {dist.pdf(6):.3f}") # 0.125
print(f"P(3 <= X <= 5) = {dist.cdf(5) - dist.cdf(3):.2f}") # 0.25
print(f"Mean = {dist.mean():.1f} | Var = {dist.var():.3f} | SD = {dist.std():.3f}") # 6.0 | 5.333 | 2.309
print(f"90th percentile = {dist.ppf(0.9):.1f}") # 9.2Beginner example (R)
a <- 2; b <- 10
cat(sprintf("P(3 <= X <= 5) = %.2f\n", punif(5, a, b) - punif(3, a, b))) # 0.25
cat(sprintf("Mean = %.1f | Var = %.3f\n", (a + b) / 2, (b - a)^2 / 12)) # 6.0 | 5.333
cat(sprintf("90th percentile = %.1f\n", qunif(0.9, a, b))) # 9.2Professional example (Python)
import numpy as np
from scipy.stats import kstest, ttest_ind
def inverse_transform_exponential(u: np.ndarray, rate: float) -> np.ndarray:
"""Turn U(0,1) draws into Exponential(rate) draws via the inverse CDF."""
return -np.log1p(-u) / rate
def aa_test_pvalue_audit(n_tests: int, n_per_arm: int, rng: np.random.Generator) -> dict[str, float]:
"""Run many A/A tests (no true effect) and check that p-values are U(0,1).
A broken pipeline (peeking, wrong variance, bad randomisation) shows up as
p-values that pile up near 0 instead of being flat.
"""
pvals = np.empty(n_tests)
for i in range(n_tests):
a = rng.normal(50, 10, n_per_arm) # e.g. basket value, same in both arms
b = rng.normal(50, 10, n_per_arm)
pvals[i] = ttest_ind(a, b).pvalue
ks = kstest(pvals, "uniform")
return {
"false_positive_rate_at_5pct": float((pvals < 0.05).mean()),
"ks_pvalue_vs_uniform": float(ks.pvalue),
}
rng = np.random.default_rng(42)
# 1. Inverse-transform sampling: time between orders, mean 4 minutes
u = rng.uniform(0, 1, 100_000)
gaps = inverse_transform_exponential(u, rate=0.25)
print(f"Mean gap between orders: {gaps.mean():.2f} min (theory 4.00)")
# 2. Log-uniform random search for a learning rate in [1e-5, 1e-1]
lrs = 10 ** rng.uniform(-5, -1, 8)
print("Random-search learning rates:", np.round(lrs, 6))
# 3. Experimentation platform audit: p-values should be uniform
print(aa_test_pvalue_audit(n_tests=2000, n_per_arm=200, rng=rng))
# Expect a false positive rate near 0.05 and a KS p-value that is not smallSource: domain knowledge