Ковариация и корреляция Пирсона

Меняются ли две величины вместе? Корреляция отвечает на этот вопрос одним числом от −1 до +1.

Корреляция Пирсона (r) — мера силы и направления линейной связи двух переменных: +1 — идеальная прямая связь, −1 — идеальная обратная, 0 — линейной связи нет.

От идеи к ковариации

Если при росте X растёт и Y — связь прямая. Если X растёт, а Y падает — обратная. Чтобы это уловить, смотрят, как X и Y отклоняются от своих средних одновременно. Когда оба чаще отклоняются в одну сторону (оба выше своих средних или оба ниже), произведение их отклонений положительно. Среднее таких произведений — это ковариация.

from statistics import mean

x = [1, 2, 3, 4, 5]
y = [2, 4, 5, 4, 6]      # в целом растёт вместе с x

mx, my = mean(x), mean(y)
# Сумма произведений отклонений
cov = sum((xi - mx) * (yi - my) for xi, yi in zip(x, y)) / len(x)
print("Среднее x:", mx, "Среднее y:", my)
print("Ковариация:", cov)

Вывод:

Среднее x: 3 Среднее y: 4.2
Ковариация: 1.6

Ковариация положительна — значит, связь прямая. Но у ковариации есть беда: её величина зависит от единиц измерения. Поменяй рубли на копейки — и ковариация вырастет в 100 раз, хотя связь та же. Нужна нормированная мера.

Корреляция: ковариация без единиц

Корреляция Пирсона решает проблему: это ковариация, делённая на произведение стандартных отклонений. Результат всегда лежит в диапазоне от −1 до +1 и не зависит от единиц.

from statistics import mean, pstdev

def pearson(x, y):
    mx, my = mean(x), mean(y)
    cov = sum((xi - mx) * (yi - my) for xi, yi in zip(x, y)) / len(x)
    return cov / (pstdev(x) * pstdev(y))

x = [1, 2, 3, 4, 5]
y = [2, 4, 5, 4, 6]
print("Корреляция:", round(pearson(x, y), 3))

Вывод:

Корреляция: 0.853

r = 0.853 — сильная положительная связь. В Python это считает и готовая функция statistics.correlation (с версии 3.10), убедимся, что числа совпадают.

from statistics import correlation

x = [1, 2, 3, 4, 5]
y = [2, 4, 5, 4, 6]
print("statistics.correlation:", round(correlation(x, y), 3))

Вывод:

statistics.correlation: 0.853

Как читать значение r

|r|Сила связи
0.0 – 0.3слабая или отсутствует
0.3 – 0.7умеренная
0.7 – 1.0сильная

Знак r — направление: плюс — прямая связь, минус — обратная. Посмотрим на три случая: прямую, обратную и отсутствие линейной связи.

from statistics import correlation

base = [10, 20, 30, 40, 50]
direct  = [15, 25, 35, 45, 55]      # растёт вместе
inverse = [55, 45, 35, 25, 15]      # падает
nolink  = [30, 10, 50, 20, 40]      # хаотично

print("Прямая связь:  ", round(correlation(base, direct), 3))
print("Обратная связь:", round(correlation(base, inverse), 3))
print("Нет связи:     ", round(correlation(base, nolink), 3))

Вывод:

Прямая связь:   1.0
Обратная связь: -1.0
Нет связи:      0.3

Идеальные прямая и обратная связи дали ровно +1 и −1, а хаотичные данные — близко к нулю. Так корреляция в одном числе сжимает характер линейной зависимости. В следующем уроке важнейшее предупреждение: корреляция — это ещё не причинность.

Итог

  • Ковариация показывает направление совместного отклонения, но зависит от единиц измерения.
  • Корреляция Пирсона — нормированная ковариация, всегда от −1 до +1.
  • Знак r — направление связи, |r| — её сила (от 0.7 связь считают сильной).
  • В Python r считает statistics.correlation (или формула вручную).
Проверьте себя
1. В каком диапазоне всегда лежит коэффициент корреляции Пирсона?
Aот 0 до 1
Bот −1 до +1
Cот −100 до +100
Dлюбое число
2. Чем корреляция удобнее ковариации?
AОна всегда больше
BОна не зависит от единиц измерения и ограничена диапазоном [−1, 1]
CЕё не нужно считать
DОна показывает причинность
3. Корреляция между переменными равна −0.9. Что это значит?
AСвязи нет
BСильная прямая связь
CСильная обратная связь: когда одна растёт, другая убывает
DОшибка в данных
Поддержать проект