Sampling & the central limit theorem in practice
You almost never measure a whole population. A bank studies 2,000 loan files, not 20 lakh; a survey firm calls 1,500 voters, not a whole state. Statistics is the art of learning about the population from a well-chosen sample - and knowing how wrong you might be.
Population, sample, statistic
| Term | Meaning | Example |
|---|---|---|
| Population | Everyone you care about | All 3.2 lakh customers of a sweets chain |
| Parameter | A true population value (usually unknown) | True mean bill value, mu |
| Sample | The subset you actually observe | 500 randomly chosen bills |
| Statistic | A value computed from the sample | Sample mean, x-bar = ₹412 |
Sampling methods
- Simple random: every unit has an equal chance -
df.sample(n=500, random_state=42). - Stratified: sample within groups (e.g. each city) so small groups are not missed -
df.groupby("city").sample(frac=0.05). - Cluster: pick whole groups (e.g. 20 random stores) and survey everyone inside - cheaper, but less precise.
- Systematic: every k-th invoice - fine unless the list has a repeating pattern.
Sampling bias beats sample size
A huge biased sample is worse than a small random one. Classic traps:
- Selection bias: an online survey misses customers who never use the app.
- Survivorship bias: studying only shops that are still open hides why others failed.
- Non-response bias: unhappy customers skip feedback forms.
The central limit theorem (CLT)
The CLT says: if you take many random samples of size n and compute each sample's mean, those means form an approximately normal distribution centred on the population mean, with spread equal to the standard error:
SE = sigma / sqrt(n)
This holds even when the underlying data is skewed, as long as n is reasonably large (30+ is a common rule of thumb; heavier skew needs more).
See it with a simulation
Bill values are strongly right-skewed - most bills are small, a few wedding orders are huge.
import numpy as np
rng = np.random.default_rng(0)
population = rng.exponential(scale=400, size=320_000) # skewed bill values in INR
print(f"Population mean: {population.mean():.0f}, sd: {population.std():.0f}")
for n in (5, 30, 200):
means = np.array([rng.choice(population, n).mean() for _ in range(5_000)])
print(f"n={n:>3} mean of means={means.mean():.0f} "
f"sd of means={means.std():.1f} theory={population.std() / np.sqrt(n):.1f}")
Plot a histogram of means for each n: at n=5 it is still skewed, at n=30 it looks bell-shaped, and at n=200 it is narrow and symmetric. The observed spread matches sigma/sqrt(n) closely.
Why this matters
- It justifies confidence intervals and t-tests on non-normal business data.
- Precision grows with the square root of n: to halve the standard error you need four times the sample.
- It applies to means (and proportions), not to individual values - a single bill can still be ₹25,000.
Common mistakes
- Believing a large sample automatically fixes bias.
- Applying the CLT to tiny samples of extremely skewed or outlier-heavy data.
- Confusing standard deviation (spread of data) with standard error (spread of an estimate).
Practice
Simulate delivery times for a Chennai food app with a log-normal distribution. Draw 3,000 samples each of size 10, 40 and 150, plot the three histograms of sample means side by side and compare the observed standard errors with sigma divided by the square root of n.