Siksha Sarovar

Siksha Sarovar (sikshasarovar.com) is a free educational web application that helps students in India learn programming and prepare for academic and competitive exams. The platform offers structured coding courses (C, C++, Python, Java, HTML, CSS, PHP, Power BI, AI, Machine Learning, Data Science), complete university curriculum notes for BCA/MCA students with previous year question papers, Class 10 and Class 12 CBSE/HBSE school notes, and dedicated preparation material for SSC, UPSC, Banking, Railway and other government exams. Browsing the site is completely free and requires no account. Users may optionally sign in with Google solely to save their learning progress, quiz scores and personal preferences across devices.

Privacy Policy | Terms of Service | Contact Siksha Sarovar | About Siksha Sarovar

v4.0.9 · PWA
Siksha Sarovar logo
Siksha Sarovar
Your Learning Universe

Siksha Sarovar is a free e-learning platform for coding courses, BCA university notes and competitive exam preparation. Optional Google sign-in saves your learning progress across devices.

Initializing knowledge base…
Compiling modules 0%

Unit 2 — Correlation and Covariance

Lesson 15 of 46 in the free Introduction to Data Analytics notes on Siksha Sarovar, written by Rohit Jangra.

Correlation

Correlation measures the strength and direction of the linear relationship between two variables. It is the first bivariate technique an analyst reaches for.

Covariance — The Foundation

              Σ(x − x̄)(y − ȳ)
  Cov(x,y) = ──────────────────        (sample, divisor n−1)
                    n − 1

Covariance tells you the direction of the relationship (positive/negative), but its magnitude depends entirely on the units — covariance between height in cm and weight in kg is a different number from height in metres and weight in grams, for identical data. That unit-dependence is exactly what correlation fixes.

Karl Pearson's Correlation Coefficient (r)

            Cov(x, y)              Σ(x − x̄)(y − ȳ)
   r = ─────────────────  =  ────────────────────────────────
            σx · σy            √[Σ(x − x̄)²] · √[Σ(y − ȳ)²]

Computational (shortcut) form:

                 n·Σxy − Σx·Σy
   r = ───────────────────────────────────────────
        √[n·Σx² − (Σx)²] · √[n·Σy² − (Σy)²]

   Range:  −1 ≤ r ≤ +1     (unit-free)

Interpreting r

rvalueStrength
0.00 – 0.19Very weak / negligible
0.20 – 0.39Weak
0.40 – 0.59Moderate
0.60 – 0.79Strong
0.80 – 1.00Very strong
rMeaning
+1Perfect positive linear relationship
0No linear relationship (a strong curved relationship may still exist!)
−1Perfect negative linear relationship

Worked Example — By Hand

Hours studied (x) vs marks (y):

xyxy
2404160080
450162500200
665364225390
870644900560
10851007225850
Σx=30Σy=310Σx²=220Σy²=20450Σxy=2080
n = 5

Numerator   = n·Σxy − Σx·Σy
            = 5(2080) − (30)(310)
            = 10400 − 9300 = 1100

Denominator = √[5(220) − 30²] × √[5(20450) − 310²]
            = √[1100 − 900] × √[102250 − 96100]
            = √200 × √6150
            = 14.142 × 78.422
            = 1108.99

r = 1100 / 1108.99 = 0.9919

Interpretation: r ≈ 0.99 — a very strong positive linear relationship. More study hours are associated with higher marks.

Coefficient of Determination (r²)

   r² = 0.9919² = 0.9839  ->  98.39%

r² is the proportion of variance in y explained by x. Here, 98.4% of the variation in marks is explained by variation in study hours; the remaining 1.6% comes from other factors.

Spearman's Rank Correlation (ρ)

Used for ordinal data, non-linear but monotonic relationships, or when outliers would distort Pearson's r.

              6 Σd²
   ρ = 1 − ─────────────       d = difference between the two ranks of an item
             n(n² − 1)                 n = number of pairs

Worked example. Ranks given by two judges:

ItemJudge AJudge Bd
P12−11
Q2111
R34−11
S4311
T5500
Σd² = 4
ρ = 1 − (6 × 4) / (5 × (25 − 1))
  = 1 − 24 / 120
  = 1 − 0.2
  = 0.8    ->  strong agreement between the judges

Pearson vs Spearman vs Kendall

BasisPearson (r)Spearman (ρ)Kendall (τ)
MeasuresLinear relationshipMonotonic relationshipConcordance of pairs
Data typeInterval/RatioOrdinal or higherOrdinal or higher
UsesActual valuesRanksRank pair ordering
Outlier sensitivityHighLowLow
Assumes normalityYes (for significance tests)NoNo
Small samplesLess reliableSuitableMost reliable

Python

import pandas as pd
import numpy as np

df = pd.DataFrame({
    "hours": [2, 4, 6, 8, 10],
    "marks": [40, 50, 65, 70, 85],
})

print("Covariance:\n", df.cov().round(2))
#         hours   marks
# hours    10.0    27.5
# marks    27.5    77.5

print("Pearson r:", round(df["hours"].corr(df["marks"]), 4))       # 0.9919
print("Spearman:", round(df["hours"].corr(df["marks"], method="spearman"), 4))  # 1.0
print("Kendall: ", round(df["hours"].corr(df["marks"], method="kendall"), 4))   # 1.0
print("r squared:", round(df["hours"].corr(df["marks"]) ** 2, 4))  # 0.9839
# Correlation matrix + significance test
from scipy import stats

data = pd.DataFrame({
    "study_hours":  [2, 4, 6, 8, 10, 3, 7, 9],
    "marks":        [40, 50, 65, 70, 85, 45, 68, 80],
    "screen_time":  [8, 7, 5, 4, 2, 7, 4, 3],
    "attendance":   [60, 70, 80, 85, 95, 65, 82, 90],
})

print(data.corr().round(3))
#              study_hours  marks  screen_time  attendance
# study_hours        1.000  0.993       -0.980       0.988
# marks              0.993  1.000       -0.977       0.995
# screen_time       -0.980 -0.977        1.000      -0.973    <- NEGATIVE correlation
# attendance         0.988  0.995       -0.973       1.000

r, p_value = stats.pearsonr(data["study_hours"], data["marks"])
print(f"r = {r:.4f}, p-value = {p_value:.6f}")
# p < 0.05  ->  the correlation is statistically significant (see hypothesis testing lesson)
# Visualising the correlation matrix as a heatmap
import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(7, 5))
sns.heatmap(data.corr(), annot=True, cmap="coolwarm", center=0, fmt=".2f",
            square=True, linewidths=0.5)
plt.title("Correlation Heatmap")
plt.tight_layout()
plt.show()

Correlation Does NOT Imply Causation

The single most important caveat in all of analytics.

Why two variables can correlate without one causing the other:

ReasonExample
Confounding (lurking) variableIce cream ↔ drowning, both caused by summer heat
Reverse causationDoes exercise cause health, or does health enable exercise?
Coincidence / spurious correlationNicolas Cage films per year vs pool drownings (a famous joke dataset)
Selection biasOnly a non-representative subset was observed
Bidirectional causationStress ↔ poor sleep, each worsening the other

Only a controlled, randomised experiment can establish causation — which is why A/B testing exists.

Anscombe's Quartet — Why You Must Also Plot

Four datasets with identical means, variances, correlations (r = 0.816) and regression lines, but completely different shapes: one linear, one curved, one linear-with-outlier, one dominated by a single point.

import seaborn as sns
df_ans = sns.load_dataset("anscombe")
print(df_ans.groupby("dataset").agg(
    x_mean=("x", "mean"), y_mean=("y", "mean"),
    corr=("x", lambda s: s.corr(df_ans.loc[s.index, "y"]))
).round(3))
# All four datasets: nearly identical statistics, wildly different scatter plots

Lesson: never report a correlation coefficient without looking at the scatter plot — the subject of a later lesson in this unit.