Chapter 4 · Statistics: Reading Data Honestly
Correlation Is Not Causation
- Page 11 of 17
- 3 min read
Two things are correlated when they tend to move together. Correlation is one of the most useful patterns in data — and one of the most misused, because "these move together" is not the same as "this causes that".
Pearson's r
The Pearson correlation coefficient, r, measures how close two variables are to a straight-line relationship. It runs from −1 to +1:
import numpy as np
rng = np.random.default_rng(1)
x = rng.uniform(0, 10, 500)
strong = 2 * x + rng.normal(0, 2, 500)
none = rng.normal(0, 5, 500)
negative = -x + rng.normal(0, 3, 500)
curved = (x - 5) ** 2 # perfectly related, but not in a straight line
for name, y in [("strong", strong), ("none", none), ("negative", negative), ("curved", curved)]:
print(f"{name:9} r = {np.corrcoef(x, y)[0, 1]:+.2f}")strong r = +0.94
none r = -0.03
negative r = -0.68
curved r = +0.00| r | Means |
|---|---|
| close to +1 | when one goes up, the other goes up, nearly in a straight line |
| close to 0 | no straight-line relationship |
| close to −1 | when one goes up, the other goes down |
Look at curved: y is completely determined by x, yet r is 0, because the relationship is a U-shape, not a line. A correlation of zero does not mean "unrelated". Plot your data before trusting a single number.
The hidden cause: confounders
Ice cream sales and the number of people swimming are strongly correlated. Does ice cream make people swim? No — hot weather drives both. A hidden variable that drives both is a confounder:
import numpy as np
rng = np.random.default_rng(3)
temperature = rng.uniform(15, 40, 1000) # daily temperature, °C
ice_cream = 20 * temperature + rng.normal(0, 60, 1000) # sales rise with heat
swimmers = 3 * temperature + rng.normal(0, 15, 1000) # so does swimming
print("ice cream vs swimmers:", np.corrcoef(ice_cream, swimmers)[0, 1].round(2))
hot = (temperature > 30) & (temperature < 32) # hold temperature (almost) fixed
print("on days of 30–32 °C only:", np.corrcoef(ice_cream[hot], swimmers[hot])[0, 1].round(2))ice cream vs swimmers: 0.73
on days of 30–32 °C only: -0.09Across all days, r = 0.73. But compare only days with almost the same temperature, and the correlation vanishes. The link was temperature all along.
Why this matters in AI
- Models learn correlations, not causes. A model that predicts loan default from postcode may really be learning about income or ethnicity — a source of unfair bias (Level 0, topic 7).
- Shortcut learning: an image model for detecting pneumonia once learned to recognise which hospital's scanner made the X-ray, because one hospital had more sick patients. It scored well in testing and failed elsewhere.
- Proving cause needs an experiment: randomly split users, change one thing for one group only (an A/B test), and compare. Randomising breaks the link with every hidden confounder.
Try it yourself
- Compute r between
hoursandmarksfrom page 7. - Make
y = x ** 2forxbetween 0 and 10 only (not centred on 5). What is r now, and why is it different fromcurved? - Think of two things that are correlated in your daily life. What might the confounder be?