Почему путаница между корреляцией и причинностью ломает выводы быстрее, чем плохая модель
В Data Science очень легко увидеть две связанные величины и мгновенно придумать между ними причинную историю. Это естественный человеческий рефлекс: мы ищем объяснение. Но данные не обязаны подтверждать интуитивный сюжет. Две переменные могут двигаться вместе из-за общего скрытого фактора, случайности, сезонности, структуры выборки или самой логики измерения. Если не различать корреляцию и причинность, можно сделать очень красивый и очень неверный вывод.
Для ML это особенно важно, потому что модель умеет использовать коррелирующий сигнал для предсказания, но это не означает, что найден причинный механизм. Предсказательная сила и причинное понимание — разные вещи.
$$ \rho_{X,Y} = \frac{\operatorname{cov}(X,Y)}{\sigma_X \sigma_Y} $$Коэффициент корреляции измеряет, насколько две переменные меняются совместно. Но сама по себе эта величина ничего не говорит о причинной связи между ними.
\rho_{X,Y}— коэффициент корреляции между X и Y\operatorname{cov}(X,Y)— ковариация двух переменных\sigma_X— стандартное отклонение X\sigma_Y— стандартное отклонение Y
Формула полезна тем, что она честно показывает ограничение: корреляция — это мера совместного движения, а не доказательство того, что X вызывает Y.
Как это выглядит на практике
Например, рост затрат на рекламу может коррелировать с ростом продаж. Но сама по себе эта корреляция не гарантирует, что продажи выросли именно из-за рекламы. Возможно, одновременно вырос спрос в сезон, изменился ассортимент или в выборку попали более сильные регионы. То же самое в продукте: длительность сессии может коррелировать с удержанием, но это не означает, что любое искусственное увеличение сессии повысит retention.
В ML это знание помогает не переоценивать interpretability модели. Даже если признак важен для предсказания, он не обязательно является рычагом управления.
import pandas as pd # создаем маленький пример совместного движения двух величин
frame = pd.DataFrame({ # задаем две связанные переменные
'ad_spend': [10, 20, 30, 40, 50], # расходы на рекламу
'sales': [100, 140, 170, 220, 260] # продажи за тот же период
})
corr = frame['ad_spend'].corr(frame['sales']) # считаем линейную корреляцию между признаками
print(round(corr, 3)) # смотрим силу совместного движенияТакой код может показать высокую корреляцию, но сам по себе он еще не дает права утверждать причинность. Именно этот разрыв и нужно постоянно держать в голове, когда данные начинают казаться слишком убедительными.