Skip to content

Beginner: data foundations · Statistics made simple · topic 10 of 62 · 30 min

Correlation: how two things move together

Explanation

Correlation measures how strongly two numeric columns move together in a straight-line way. Pearson's r runs from −1 (perfectly opposite) through 0 (no straight-line link) to +1 (perfectly together). A strong correlation does not prove that one thing causes the other: a hidden third factor often drives both.

Why look at two columns together

So far each summary described one column. Many real questions are about pairs: do students who study more score higher? Do houses closer to a metro station cost more? Does more advertising bring more sales? The first step is a scatter plot, and the first number is the correlation.

Scatter plots

A scatter plot puts one column on the x-axis and the other on the y-axis, with one dot per row. If the dots rise from left to right, the link is positive; if they fall, negative; if they form a shapeless cloud, there is no clear link. Always look at the plot before trusting any number.

python
import matplotlib.pyplot as plt

hours = [1, 2, 3, 4, 5]
marks = [52, 55, 61, 64, 70]
plt.scatter(hours, marks)
plt.xlabel("Hours studied per day")
plt.ylabel("Marks")
plt.show()
Shown only: the five dots climb steadily from left to right.

Covariance

Covariance measures whether two columns move in the same direction. For each row, take x's deviation from its mean times y's deviation from its mean. When both are above their means (or both below), the product is positive; when one is above and the other below, it is negative. Average these products (dividing by n − 1 for a sample) and you get the covariance. Positive means "move together", negative means "move opposite".

The problem: covariance has strange units (hours × marks) and its size changes if you switch from rupees to thousands of rupees. So you cannot tell from it whether a link is strong or weak.

Pearson's correlation coefficient r

Pearson's r fixes that by dividing the covariance by the two standard deviations: r = covariance / (sd of x × sd of y). The units cancel, and r always lands between −1 and +1. Use the same divisor (n or n − 1) for the covariance and both SDs, and it cancels out, so r is the same either way.

rMeaning
+1Perfect straight line going up
about +0.7 to +0.9Strong positive link
about 0No straight-line link
about −0.7 to −0.9Strong negative link
−1Perfect straight line going down
python
hours = [1, 2, 3, 4, 5]
marks = [52, 55, 61, 64, 70]
n = len(hours)
mx = sum(hours) / n   # 3.0
my = sum(marks) / n   # 60.4

cov = sum((x - mx) * (y - my) for x, y in zip(hours, marks)) / (n - 1)
sx = (sum((x - mx) ** 2 for x in hours) / (n - 1)) ** 0.5
sy = (sum((y - my) ** 2 for y in marks) / (n - 1)) ** 0.5
print(round(cov, 2))             # 11.25
print(round(cov / (sx * sy), 3)) # 0.993
A very strong positive link in this small made-up sample.
python
import statistics

print(round(statistics.correlation(hours, marks), 3))   # 0.993
print(statistics.covariance(hours, marks))              # 11.25
statistics.correlation and statistics.covariance need Python 3.10 or newer; covariance uses the sample formula (n − 1). In pandas: df["hours"].corr(df["marks"]).

r measures straight lines only

r only detects straight-line (linear) patterns. A perfect U-shaped curve can have r = 0. And a single outlier can push r up or down a lot. That is why you always draw the scatter plot first.

python
xs = [-2, -1, 0, 1, 2]
ys = [x * x for x in xs]   # [4, 1, 0, 1, 4]: a perfect U shape
print(statistics.correlation(xs, ys))   # 0.0
y depends completely on x, yet r is 0, because the pattern is not a straight line.

Correlation is not causation

Ice-cream sales and drowning deaths rise and fall together. Ice-cream does not cause drowning. Hot weather drives both: more people buy ice-cream and more people swim. A hidden factor that drives both variables is called a confounder. In India, umbrella sales and dengue cases both rise in the monsoon, and the rain is the confounder.

  • Confounder: a third factor causes both (summer heat, the monsoon).
  • Reverse cause: the arrow points the other way (hospitals have many sick people, but hospitals do not make people sick).
  • Chance: with enough columns, some pairs correlate by pure luck.
Tip: To show cause and effect you usually need an experiment, such as an A/B test where people are randomly split into groups. Module 3 covers this.

Common mistakes

  • Saying "X causes Y" from a correlation. Fix: say "X and Y are associated", and list possible confounders.
  • Trusting r without a scatter plot. Fix: always plot; look for curves, clusters and outliers.
  • Reading r = 0 as "no relationship". Fix: it means no straight-line relationship; there may be a curve.
  • Computing r on tiny samples. Fix: with 5 points, r can be large by chance; collect more data.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Correlation: how two things move together · 1/7

Correlation

In this lesson you will measure how two things move together, and learn why that does not prove one causes the other.

Prefer a video by a teacher? Find free videos on “pearson correlation coefficient explained correlation vs causation” on YouTube ↗

In real life: Advertising and sales at a retail chain

A retail chain notices that stores with bigger local advertising budgets have higher sales: the correlation is strongly positive. Before spending more, a careful analyst asks: are the big-budget stores also in richer, busier areas? Store location could be a confounder that drives both the budget and the sales. To measure the real effect of advertising, the company runs a test: it raises the ad budget in randomly chosen stores and compares them with similar stores where it does not. The numbers below are made up.

python
import statistics

ad_spend = [20, 35, 50, 65, 80]      # ₹ thousand per month
sales = [310, 340, 420, 400, 470]    # ₹ thousand per month
print(round(statistics.correlation(ad_spend, sales), 2))
Output: 0.94. A strong link, but not yet proof that advertising causes the sales.

Practice (0/3 done)

Task 1 · Code · Python

Without the statistics module, write sample_covariance(xs, ys) that returns the sample covariance: the sum of (x − mean of xs) × (y − mean of ys) over all pairs, divided by n − 1, rounded to 2 decimal places. If the lists have different lengths or fewer than 2 values, return None.

Task 2 · Code · Python

Without the statistics module, write pearson_r(xs, ys) that returns Pearson's correlation coefficient rounded to 3 decimal places. Return None if the lists have different lengths, have fewer than 2 values, or if either list has no spread (all values equal).

Task 3 · Practice

A news headline says: "Cities with more coaching centres have more students who clear competitive exams, so coaching causes success." Write a short reply (4–6 sentences) explaining what the data does and does not show, and how you could test the claim more fairly.

Quick quiz

Question 1

1.r = −0.85 between a car's age and its resale price. What does that mean?

Question 2

2.Umbrella sales and dengue cases rise together each year. What is the most likely explanation?

Question 3

3.A scatter plot shows a perfect U shape, but r is close to 0. What is true?

Question 4

4.Why is r easier to interpret than covariance?

Question 5

5.Which Python call gives Pearson's r directly (Python 3.10+)?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

r = −0.85 between a car's age and its resale price. What does that mean?

Answer: Older cars tend to sell for less, a strong link

A strong negative r means one goes up while the other tends to go down. It does not give a percentage effect.

Umbrella sales and dengue cases rise together each year. What is the most likely explanation?

Answer: A confounder, the monsoon rain, drives both

Rain brings both umbrella buying and mosquito breeding. That third factor is a confounder.

A scatter plot shows a perfect U shape, but r is close to 0. What is true?

Answer: r only measures straight-line relationships, so it misses the curve

r measures linear association; a strong curved pattern can still give r near 0.

Why is r easier to interpret than covariance?

Answer: It has no units and always lies between −1 and +1

Dividing by both SDs cancels the units, so r can be compared across any pair of columns.

Which Python call gives Pearson's r directly (Python 3.10+)?

Answer: statistics.correlation(xs, ys)

statistics.correlation was added in Python 3.10. There is no statistics.pearson function.

Which point does the least-squares line always pass through?Related

Answer: (x̄, ȳ), the two means

Because b = ȳ − w·x̄, the line goes through the mean point.

From Linear regression and least squares

In an exam with mean 60 and SD 10, what is the z-score of 45?Related

Answer: -1.5

z = (45 − 60) / 10 = −1.5: one and a half SDs below the mean.

From The normal distribution and z-scores

What is a correlation ID (request ID) for?Related

Answer: Finding all log lines, across services, that belong to one request

The same ID in every line lets you follow one request across many services.

From Logging: structured, safe and centralised

Which measure of spread is most affected by a single extreme value?Related

Answer: The range

The range uses only the smallest and largest values, so one outlier changes it completely. The median and mode are not measures of spread.

From Spread: range, variance and standard deviation

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. This is the last topic of “Statistics made simple”. The module exam comes next.
  2. Module 2 exam: Statistics made simple · 14 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Probability and inference. 62 topics left in the course before the final exam.

← Previous: The normal distribution and z-scores