Statistics Correlation

Correlation measures the strength and direction of a straight-line relationship between two numeric variables, ranging from -1 to +1.

What the Correlation Coefficient Tells You

The correlation coefficient, usually written r, is a single number between -1 and +1 that summarizes how closely two numeric variables move together in a straight-line pattern. A positive r means that as one variable increases, the other tends to increase too; a negative r means one tends to fall as the other rises; and the closer the magnitude of r is to 1, the tighter that pattern is.

Example

import math

def correlation(x, y):
    n = len(x)
    mean_x = sum(x) / n
    mean_y = sum(y) / n
    cov = sum((x[i] - mean_x) * (y[i] - mean_y) for i in range(n))
    std_x = math.sqrt(sum((xi - mean_x) ** 2 for xi in x))
    std_y = math.sqrt(sum((yi - mean_y) ** 2 for yi in y))
    return cov / (std_x * std_y)

hours_studied = [1, 2, 3, 4, 5, 6, 7]
exam_score =   [52, 58, 63, 68, 74, 77, 83]

r = correlation(hours_studied, exam_score)
print("r =", round(r, 3))

Correlation Is Not Causation

Suppose you notice that, across different months, ice cream sales and the number of people who go swimming both rise and fall together - a strong positive correlation. That doesn't mean ice cream causes swimming, or the other way around. Both are driven by a third factor: warm weather. This kind of hidden driver is called a confounding (or lurking) variable, and it's exactly why a strong correlation between two things is never, by itself, proof that one causes the other.

Note: Correlation measures association, not causation. Two variables can be strongly correlated because one causes the other, because they share a common cause, because of coincidence in a small dataset, or because of how the data was collected. Establishing causation generally requires controlled experiments or careful causal-inference methods, not just a correlation coefficient.

What Correlation Can Miss

Because r only measures straight-line association, two variables can have a strong, obvious relationship that curves - and still show an r close to zero. Correlation is also sensitive to outliers: a single extreme point can drag the coefficient much higher or lower than what the bulk of the data would suggest.

Example

def correlation(x, y):
    n = len(x)
    mean_x = sum(x) / n
    mean_y = sum(y) / n
    cov = sum((x[i] - mean_x) * (y[i] - mean_y) for i in range(n))
    std_x = (sum((xi - mean_x) ** 2 for xi in x)) ** 0.5
    std_y = (sum((yi - mean_y) ** 2 for yi in y)) ** 0.5
    return cov / (std_x * std_y)

x = [2, 4, 5, 7, 8, 9]
y = [3, 5, 6, 8, 9, 40]   # last point is a wild outlier

print("r with outlier:", round(correlation(x, y), 3))
print("r without outlier:", round(correlation(x[:-1], y[:-1]), 3))
r valueTypical interpretation
0.9 to 1.0 (or -0.9 to -1.0)Very strong relationship
0.7 to 0.9Strong relationship
0.4 to 0.7Moderate relationship
0.1 to 0.4Weak relationship
0 to 0.1Little to no linear relationship
  • Always plot the data - very different patterns can produce the same r value
  • Check for outliers that might be inflating or deflating the coefficient
  • Consider whether a lurking (confounding) variable could explain both variables moving together
  • Remember r only captures straight-line relationships, not curves or other patterns
Note: Correlation is symmetric - corr(x, y) is exactly the same number as corr(y, x) - but that symmetry disappears once you move to regression, where predicting y from x gives a different line than predicting x from y.