Correlation measures whether two variables move together — nothing more. A strong r can come from X causing Y, Y causing X, a hidden confounder Z driving both, selection effects, or plain chance. Simpson's paradox is the most dramatic failure: a trend that holds in every subgroup can reverse when the groups are pooled.
| Why X and Y correlate | Example | Antidote |
|---|---|---|
| X causes Y | Price cut → more sales | Randomized experiment confirms it |
| Y causes X | More police ↔ more crime (reverse) | Temporal ordering, natural experiments |
| Confounder Z | Ice cream ↔ drownings (summer) | Stratify or control for Z |
| Selection bias | Only survivors measured | Audit how the sample was formed |
| Chance | Any two trending series | Out-of-sample checks, corrections |
- Before trusting any correlation, list plausible confounders — time, size, cohort, seasonality are the usual suspects
- Recompute the relationship within each stratum of the confounder (groupby is enough)
- If pooled and stratified trends disagree, resolve it with causal knowledge, not with more data
- For decisions that matter, push for a randomized test — it severs every confounder at once
pip install pandas seaborn
# ────────────────────────────────────────
import seaborn as sns
df = sns.load_dataset('penguins').dropna()
pooled = df['bill_length_mm'].corr(df['bill_depth_mm'])
within = df.groupby('species').apply(
lambda g: g['bill_length_mm'].corr(g['bill_depth_mm']))
print(f"pooled r = {pooled:.2f}") # negative!
print(within.round(2)) # all positive
Talent and looks are independent in 20,000 people (r = −0.002). Look only at the 1,568 who are noticed because their sum is high, and the correlation is −0.75: among the famous, the talented seem plain and the beautiful seem untalented. Selecting on an outcome creates correlations that do not exist — Berkson’s paradox, or collider bias.
- Collider bias is created by conditioning — through selection, filtering or “controlling for” a variable that both causes affect.
- Datasets of applicants, patients or customers are already selected; correlations inside them can be artefacts.
- Adding more variables to a regression does not fix this; adding the wrong one causes it.
rng = np.random.default_rng(21) talent, looks = rng.normal(size=(2, 20_000)) # independent in the population famous = talent + looks > 2 # only the top on the sum get noticed r_all = np.corrcoef(talent, looks)[0, 1] r_famous = np.corrcoef(talent[famous], looks[famous])[0, 1]
Assumes import numpy as np and import pandas as pd (and SciPy where imported). Each snippet simulates or makes up its own data, as the comments say.
The same idea with a library
# Python — Simpson's paradox in three lines of groupby import pandas as pd # Pooled correlation says one thing… print(df[['dose', 'recovery']].corr().iloc[0, 1]) # …every subgroup says the opposite print(df.groupby('severity') .apply(lambda g: g['dose'].corr(g['recovery']))) # Always check candidate confounders before trusting a trend pd.crosstab(df['severity'], df['treatment'], normalize='index')
- J. Berkson, “Limitations of the Application of Fourfold Table Analysis to Hospital Data”, Biometrics Bulletin 2(3), 1946
- Causal Inference in Statistics: A Primer, J. Pearl, M. Glymour & N. P. Jewell, Wiley, 2016
- F. Elwert & C. Winship, “Endogenous Selection Bias: The Problem of Conditioning on a Collider Variable”, Annual Review of Sociology 40, 2014
Last reviewed October 2026 · How this site checks its content · Report a mistake
1. Across a year, ice-cream sales and drownings rise and fall together. What is the best explanation?
Show answer
B. Warm days bring both ice cream and swimming. The correlation is real and even useful for forecasting; it just runs through a confounder rather than from one to the other.
2. Two variables have a correlation of r = 0. What does that tell you?
Show answer
C. Pearson’s r only measures straight-line association. If x is symmetric around zero, y = x² is completely determined by x and still has r ≈ 0. Plot the data.
3. Which evidence best supports a causal claim?
Show answer
A. Randomization makes the groups alike in everything except the treatment, confounders included. More observational data makes a biased estimate more precise, not less biased.