Skip to content
C.W.K.
Stream
Lesson 04 of 06 · published

When the CLT Quietly Fails

~12 min · clt, failure-modes, dependence, fat-tails, preview-track-07

Level 0Stats Novice
0 XP0/55 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete
"A normal approximation is a conclusion with conditions. Check dependence, tails, dominant terms, and finite-sample accuracy before using it."

The Two Preconditions, Reviewed

The simplest iid CLT uses:

  1. Independent, identically distributed terms.
  2. A finite mean and variance.

When both hold, the standardized sum converges to a normal as N grows. When either fails, the conclusion no longer follows. The bell may still appear, but for the wrong reasons, or it may not appear at all — and either way, downstream tools that assumed normality are now mistaken.

Failure Mode 1: Hidden Dependence

If dependence is ignored, the variance of a sum is miscomputed because covariance terms are missing. Some dependent sequences still satisfy CLTs with an appropriate long-run variance, and jointly normal correlated variables have normal sums. The problem is using an independence formula when the dependence structure says otherwise.

Financial risk models illustrate the broader issue: dependence, volatility, and liquidity can all change between calibration and crisis periods. In crises, correlations and liquidity can change sharply, so a model calibrated to calm periods may understate joint losses. Correlations do not universally become 1, and the failure is broader than one CLT condition. The lesson is to model the relevant dependence and regime, not to blame one theorem.

Failure Mode 2: Infinite Variance

The standard CLT needs each X to have a finite variance. Under the common survival-tail convention P(X>x) ∝ x^(−α), α ≤ 2 implies infinite variance; other parameterizations use different thresholds. The ordinary finite-variance CLT then does not apply. Instead, sums of such variables converge to stable distributions, which can be heavy-tailed and asymmetric. A differently scaled sum may converge to a stable law. Whether a population mean exists depends on the tail index; the sample mean can remain meaningful even when the usual normal standard error is not.

Earthquake size measures, file sizes, social reach, and returns can be heavy-tailed, but the fitted family and tail index are empirical questions and differ across definitions and datasets. A mean may or may not exist and may be difficult to estimate; report the tail model and robust summaries suited to the question.

Failure Mode 3: Slow Convergence

Even when independence and finite variance both technically hold, the CLT can be slow to converge when the individual X's are very skewed or heavy-tailed (but with technically finite variance, like the lognormal). 'N is large enough' becomes a function of how non-normal the underlying X's are. For a highly skewed X, N=30 might be wildly insufficient; N=10,000 might still be wrong in the tails. The CLT is asymptotic — finite samples are always approximations.

The Citizen's Test

Before trusting a bell-shaped assumption, run the precondition check: are the underlying X's plausibly independent? Is the variance plausibly finite? Is N large enough relative to how non-normal the X's are? If any answer is 'no' or 'I don't know,' the bell is a guess, not a derivation. Track 07 will dismantle the worst real-world consequences of skipping this test.

Code

CLT under hidden correlation·python
import numpy as np
rng = np.random.default_rng(60)

# Show CLT failing under correlation.
# Sum of N=100 highly-correlated variables vs N=100 independent ones.
N = 100
M = 10_000

# Independent draws.
independent = rng.normal(size=(M, N))
sum_indep = independent.sum(axis=1)

# Correlated draws — all share a common factor.
common = rng.normal(size=(M, 1))
idiosync = rng.normal(size=(M, N))
correlated = 0.7 * common + 0.3 * idiosync
sum_corr = correlated.sum(axis=1)

# Standardize both.
def stats(x, label):
    z = (x - x.mean()) / x.std()
    p4 = (np.abs(z) > 4).mean()
    print(f"{label:>25s}: std={x.std():>7.2f}  P(|z|>4)={p4:.4f}")

stats(sum_indep, "independent (CLT holds)")
stats(sum_corr, "correlated (CLT broken)")

# The independent sum has the bell-like P(|z|>4) ~ 0.0001.
# The correlated sum's standard deviation is much larger because variance
# accumulates beyond the independence-assumed bound — but the bell-of-
# z still looks fine when you standardize. The trouble is the RAW values:
# extreme outcomes happen far more often than independence would predict.

External links

Exercise

Pick a quantity in your work or life where you suspect hidden correlation between supposedly-independent observations (responses to a single email, traffic on different parts of your site, replies during a viral moment). Estimate: would the CLT's prediction of 'rare events' underestimate or overestimate the real-world frequency? Almost always: underestimate, because correlation amplifies tail behavior.
Hint
If observations share a common cause (a news event, a celebrity tweet, a system outage), their independence is illusory and the bell-derived 'this is a 1-in-a-million event' will fire much more often than once in a million.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue
💛 by Ttoriwarm

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.