February 5, 2021

Как определять зависимости на практике

-  Билл, уровень продаж не стабилен, хотя средства на маркетинг  расходуются колоссальные,  босс требует отчета о взаимосвязях между  финансами, затраченными на каждый источник рекламы, и объемами продаж.  Билл озадачен, он только получил высшее образование, знает формулу для  подсчета коэффициента корреляции (Pxy), но некоторыми величинами не  располагает. Как ему выйти из этой ситуации?

Действительно, есть стандартная формула подсчета:

Pxy = E(X-Ex)(Y-Ey) / (Sx*Sy), где

Ex, Ey -  математические ожидания случайных величин X и Y,

Sx и Sy - стандартные отклонения X и Y (подробнее о понятиях  рассказывал здесь);

В случае, если обе случайные величины X и Y дискретные, то формула приобретает вид:

Таким  образом, в теории нам может быть дано совместное распределение  случайных величин (то есть все вероятности P(X=Xi, Y=Yj)), но в  реальности мы может только пользоваться их оценками. Так, на практике мы  всего лишь наблюдаем n пар значений (Xi,Yi), соответственно, формулу  необходимо видоизменить:

На  этом шаге мы избавились от совместных вероятностей. Формула идентична  при большом количестве наблюдаемых пар n, так как в этом случае при  группировке всех одинаковых пар значений (Xi,Yj), получим множители  равные вероятностям из первой формулы. Следует отметить, что на практике  и математическое ожидание, и стандартное отклонение в формуле также  заменяются их оценками.

Рассмотрим как можно адаптировать к практике условия ранее  рассмотренной задачи о взаимосвязи случайных величин X -  погода и Y -  длительность времени в пути (взята из книги "Введение в  эконометрику"  Д.Сток, М. Уотсон). Напомню, что нам давалась следующая таблица  их  совместного распределения:

Если  сформировать вектор X из 30 '0' и 70 '1', а вектор Y последовательно из  15 '0', 15 '1', 7 '0', 63 '1', получим такие же попарные вероятности.   Подсчитаем в Python коэффициент корреляции, используя  функцию pearsonr модуля scipy.stats:

from scipy.stats import pearsonr

x = [0]*30+[1]*70
y = [0]*15 +[1]*15+[0]*7+[1]*63
pearsonr(x,y)

То есть мы получили величину (первое число) в точности равную подсчитанной ранее вручную. Замечу, что второе значение обозначает вероятность того, что X и Y сгенерированы некоррелированной системой.

Напоследок  продемонстрирую, что  коэффициент корреляции хорошо определяет линейную  взаимосвязь между величинами. Рассмотрим график:

Очевидна взаимосвязь между X и Y (2*X - 1 + шум), коэффициент корреляции будет равен - 0.92.

Теперь рассмотрим другой случай, когда Y = X**2:

В этом случае также очевидна взаимосвязь между X и Y, но коэффициент корреляции близок к 0.

Ниже представляю код на Python для вывода графиков и подсчета коэффициента корреляции:

from scipy.stats import pearsonr
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
sns.set()
SMALL_SIZE = 12
MEDIUM_SIZE = 14
BIGGER_SIZE = 18

plt.rc('font', size=MEDIUM_SIZE)          # controls default text sizes
plt.rc('axes', titlesize=BIGGER_SIZE)     # fontsize of the axes title
plt.rc('axes', labelsize=MEDIUM_SIZE)    # fontsize of the x and y labels
plt.rc('xtick', labelsize=SMALL_SIZE)    # fontsize of the tick labels
plt.rc('ytick', labelsize=SMALL_SIZE)    # fontsize of the tick labels
plt.rc('legend', fontsize=SMALL_SIZE)    # legend fontsize
plt.rc('figure', titlesize=BIGGER_SIZE)  # fontsize of the figure title

np.random.seed(1)
# последовательность 100 равноудаленных точек
# на отрезке от -2 до 2    
x = np.linspace(-2,2,100)
# линейна связь с добавлением небольшого шума,
# имеющего стандартное нормальное распределение
y = 2*x - 1 + np.random.normal(0,1,100)
plt.scatter(x,y)
plt.title('Диаграмма рассеяния X и Y')
plt.xlabel('X')
plt.ylabel('Y')

pearsonr(x,y)

y=x**2
plt.scatter(x,y)
plt.title('Диаграмма рассеяния X и Y')
plt.xlabel('X')
plt.ylabel('Y')

pearsonr(x,y)

Вот такие подводные камни имеет корреляция. А с какими необычными зависимостями сталкивались вы?