Pearson Correlation Coefficient
The Pearson correlation coefficient, written r, is the most widely used measure of correlation. It expresses the linear relationship between two numeric variables as a single number between -1 and +1.
Formula
sum( (xi - x_mean) * (yi - y_mean) )
r = ---------------------------------------------
sqrt( sum(xi - x_mean)^2 ) * sqrt( sum(yi - y_mean)^2 )
where
xi,yi= the i-th values of X and Y,x_mean,y_mean= the averages of X and Y.
The numerator is the covariance (do they vary together?). The denominator scales it by both standard deviations so that r has no units and stays within [-1, 1].
Manual example
X = [1, 2, 3, 4, 5], Y = [5, 7, 3, 9, 1]
| Step | Calculation | Result |
|---|---|---|
| Mean of X | (1+2+3+4+5)/5 | 3 |
| Mean of Y | (5+7+3+9+1)/5 | 5 |
| Deviations of X | -2, -1, 0, 1, 2 | |
| Deviations of Y | 0, 2, -2, 4, -4 | |
| Products | 0, -2, 0, 4, -8 | sum = -6 |
| Sum of X deviations squared | 4+1+0+1+4 | 10 |
| Sum of Y deviations squared | 0+4+4+16+16 | 40 |
| r | -6 / sqrt(10 x 40) = -6 / 20 | -0.3 |
So r = -0.3: a weak negative correlation.
Verify with Python
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([5, 7, 3, 9, 1])
dx, dy = x - x.mean(), y - y.mean()
r = (dx * dy).sum() / np.sqrt((dx**2).sum() * (dy**2).sum())
print(r) # -0.3
print(np.corrcoef(x, y)[0, 1]) # -0.3 (same)
Interpreting the size of r
A common guide (the exact cut-offs differ by field):
| |r| | Strength | |---|---| | 0.80 - 1.00 | Perfect / very strong | | 0.50 - 0.79 | Strong | | 0.30 - 0.49 | Moderate | | 0.00 - 0.29 | Weak |
Many practitioners treat |r| above 0.7 as strong. The sign gives the direction: + means both increase together, - means one goes up while the other goes down.
r-squared is the "share of variance explained". If r = 0.7 then r-squared = 0.49, meaning about 49% of the variation in one variable is linearly explained by the other.
Assumptions and warnings
- Both variables are numeric (interval/ratio).
- The relationship is roughly linear.
- No extreme outliers - one outlier can create or destroy a correlation.
- Approximately normal distribution (mainly matters for significance tests).
- Small samples give unstable r values; report a p-value or confidence interval when the sample is small.
from scipy import stats
r, p = stats.pearsonr(x, y)
print(f"r = {r:.2f}, p-value = {p:.3f}") # large p: could easily be chance