Корреляция и ковариация

Корреляция в одном числе от −1 до 1 говорит, насколько две величины меняются вместе — растут вместе, падают вместе или не связаны.

Ковариация — средняя величина совместного отклонения двух переменных от их средних. Корреляция — ковариация, нормированная на стандартные отклонения, диапазон от −1 до 1.

Ковариация: меняются ли вместе

Ковариация смотрит на пары значений: когда X выше своего среднего, Y тоже выше (тогда произведение отклонений положительно) или ниже (отрицательно)? Усреднив эти произведения, получаем ковариацию. Знак говорит о направлении связи, но величина зависит от единиц измерения — поэтому «голую» ковариацию трудно интерпретировать.

import statistics

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

mx = statistics.mean(xs)
my = statistics.mean(ys)
n = len(xs)

cov = sum((x - mx) * (y - my) for x, y in zip(xs, ys)) / n
print("Среднее X:", mx, " Среднее Y:", my)
print("Ковариация:", round(cov, 4))

Вывод:

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

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

Чтобы избавиться от зависимости от единиц, ковариацию делят на произведение стандартных отклонений — получается коэффициент корреляции Пирсона в диапазоне от −1 до 1. Теперь число легко читать: +1 — идеальная прямая связь, −1 — идеальная обратная, 0 — линейной связи нет.

import math, statistics

def correlation(xs, ys):
    mx, my = statistics.mean(xs), statistics.mean(ys)
    n = len(xs)
    cov = sum((x - mx) * (y - my) for x, y in zip(xs, ys)) / n
    sx = math.sqrt(sum((x - mx) ** 2 for x in xs) / n)
    sy = math.sqrt(sum((y - my) ** 2 for y in ys) / n)
    return cov / (sx * sy)

xs = [1, 2, 3, 4, 5]
print("Растут вместе :", round(correlation(xs, [2, 4, 5, 4, 6]), 4))
print("Обратная связь:", round(correlation(xs, [10, 8, 6, 4, 2]), 4))
print("Нет связи     :", round(correlation(xs, [5, 1, 5, 1, 5]), 4))
print("Проверка stdlib:", round(statistics.correlation(xs, [2, 4, 5, 4, 6]), 4))

Вывод:

Растут вместе : 0.8528
Обратная связь: -1.0
Нет связи     : 0.0
Проверка stdlib: 0.8528

Идеально убывающий ряд дал корреляцию −1, симметричный «зигзаг» — 0. Наша ручная формула совпала со встроенной statistics.correlation.

Корреляция ≠ причинность

Самая важная оговорка статистики. Высокая корреляция не означает, что одно вызывает другое. Продажи мороженого коррелируют с числом утоплений — но мороженое не топит людей, у них общая причина (жара). В ML это критично: модель ловит корреляции, и если не подумать, она примет ложную связь за настоящую закономерность.

КорреляцияСмысл
близко к +1сильная прямая связь (растут вместе)
близко к −1сильная обратная связь (одно растёт, другое падает)
около 0линейной связи нет

В ML корреляцию используют для отбора признаков (сильно коррелирующие с целью — полезны) и для поиска избыточных признаков (две почти одинаковые колонки коррелируют между собой — одну можно убрать).

Итог

  • Ковариация измеряет совместное отклонение от средних, но зависит от единиц.
  • Корреляция = нормированная ковариация в диапазоне [−1, 1], легко интерпретируется.
  • +1 — прямая связь, −1 — обратная, 0 — нет линейной связи.
  • Корреляция не равна причинности; в ML её используют для отбора признаков.
Проверьте себя
1. Чем корреляция удобнее ковариации?
AОна быстрее вычисляется
BОна нормирована в диапазон [−1, 1] и не зависит от единиц измерения
CОна всегда положительна
DОна учитывает причинность
2. Что означает коэффициент корреляции, близкий к −1?
AПеременные не связаны
BСильная обратная связь: когда одна растёт, другая падает
CСильная прямая связь
DОшибку в расчётах
3. Почему «корреляция не равна причинности» важно для ML?
AКорреляция всегда ложна
BМодель ловит корреляции и может принять ложную связь (общая причина, совпадение) за настоящую закономерность
CПричинность вычисляется той же формулой
DЭто не относится к ML
Поддержать проект