Расчет коэффициента корреляции Пирсона в Python с помощью Numpy

Введение Эта статья представляет собой введение в коэффициент корреляции Пирсона, его вычисление вручную и его вычисление с помощью модуля Python numpy. Коэффициент корреляции Пирсона измеряет линейную связь между переменными. Его значение можно интерпретировать так: * +1 - полная положительная корреляция * +0,8 - сильная положительная корреляция * +0,6 - умеренная положительная корреляция * 0 - никакой корреляции * -0,6 - умеренная отрицательная корреляция * -0,8 - сильная отрицательная

Вступление

Эта статья представляет собой введение в коэффициент корреляции Пирсона , его вычисление вручную и вычисление с помощью модуля numpy

Коэффициент корреляции Пирсона измеряет линейную связь между переменными. Его значение можно интерпретировать так:

  • +1 - Полная положительная корреляция
  • +0,8 - Сильная положительная корреляция
  • +0.6 - Умеренная положительная корреляция
  • 0 - никакой корреляции
  • -0.6 - Умеренная отрицательная корреляция
  • -0,8 - Сильная отрицательная корреляция
  • -1 - Полная отрицательная корреляция

Мы проиллюстрируем, как меняется коэффициент корреляции с разными типами ассоциаций. В этой статье мы также покажем, что нулевая корреляция не всегда означает нулевую ассоциацию . Нелинейно связанные переменные могут иметь коэффициенты корреляции, близкие к нулю.

Что такое коэффициент корреляции Пирсона?

Коэффициент корреляции Пирсона также известен как коэффициент корреляции произведение Пирсона и момента . Это мера линейной связи между двумя случайными величинами - X и Y. Математически, если ( σXY ) - ковариация между X и Y , а ( σX ) - стандартное отклонение X , то коэффициент корреляции Пирсона ρ определяется как:

$$
\ rho_ {X, Y} = \ frac {\ sigma_ {XY}} {\ sigma_X \ sigma_Y}
$

Поскольку ковариация всегда меньше, чем произведение индивидуальных стандартных отклонений, значение ρ варьируется от -1 до +1 . Из вышесказанного мы также можем видеть, что корреляция переменной с самой собой равна единице:

$$
\ rho_ {X, X} = \ frac {\ sigma_ {XX}} {\ sigma_X \ sigma_X} = 1
$
Прежде чем мы начнем писать код, давайте сделаем небольшой пример, чтобы увидеть, как вычисляется этот коэффициент.

Как рассчитывается коэффициент корреляции Пирсона?

Предположим, нам даны некоторые наблюдения случайных величин X и Y. Если вы планируете реализовать все с нуля или провести некоторые расчеты вручную, то при заданных X и Y вам понадобится следующее:

$$\begin{matrix} {Икс} & \operatorname{знак\ равно} & \lbrack & {- 2} & {- 1} & 0 & 1 & 2 & \rbrack^{Т} \
Y & \operatorname{знак\ равно} & \lbrack & 4 & 1 & 3 & 2 & 0 & \rbrack^{Т} \
{Икс}^{2} & \operatorname{знак\ равно} & \lbrack & 4 & 1 & 0 & 1 & 4 & \rbrack^{Т} \
Y^{2} & \operatorname{знак\ равно} & \lbrack & 16 & 1 & 9 & 4 & 0 & \rbrack^{Т} \
{{Икс}Y} & \operatorname{знак\ равно} & \lbrack & {- 8} & {- 1} & 0 & 2 & 0 & \rbrack^{Т} \
\end{matrix}$$

Давайте воспользуемся приведенным выше, чтобы вычислить корреляцию. Мы будем использовать смещенную оценку ковариации и стандартных отклонений. Это не повлияет на значение вычисляемого коэффициента корреляции, поскольку количество наблюдений сокращается в числителе и знаменателе:

$$\begin{matrix} \sigma_{{Икс}Y} & \operatorname{знак\ равно} & {E({Икс}Y) - E({Икс})E(Y)} & {\operatorname{знак\ равно} - 7/5 - (0)(2)} & {\operatorname{знак\ равно} - 7/5} \
\sigma_{Икс} & \operatorname{знак\ равно} & \sqrt{E({Икс}^{2}) - (E({Икс}))^{2}} & {\operatorname{знак\ равно}\sqrt{10/5 - (0)^{2}}} & {\operatorname{знак\ равно}\sqrt{2}} \
\sigma_{Y} & \operatorname{знак\ равно} & \sqrt{E(Y^{2}) - (E(Y))^{2}} & {\operatorname{знак\ равно}\sqrt{30/5 - (10/5)^{2}}} & {\operatorname{знак\ равно}\sqrt{2}} \
\rho_{{Икс}Y} & \operatorname{знак\ равно} & \frac{\frac{- 7}{5}}{\sqrt{2}\sqrt{2}} & {\operatorname{знак\ равно} - 7/10} & \
\end{matrix}$$

Коэффициент корреляции Пирсона в Python с использованием Numpy

Коэффициент корреляции Пирсона можно вычислить в Python с помощью corrcoef() из Numpy.

mxn для этой функции обычно является матрица, скажем, размером mxn, где:

  • Каждый столбец представляет значения случайной переменной.
  • Каждая строка представляет собой одну выборку из n случайных величин.
  • n представляют собой общее количество различных случайных величин
  • m представляет собой общее количество выборок для каждой переменной

Для n случайных величин он возвращает квадратную матрицу M nxn , где M(i,j) указывает коэффициент корреляции между случайной величиной i и j . Поскольку коэффициент корреляции между переменной и самим собой равен 1, все диагональные элементы (i,i) равны единице.

Коротко:

$$M(я,j)\operatorname{знак\ равно}\left{ \begin{matrix} \rho_{я,j} & {\text{если}я \neq j} \
1 & \text{иначе} \
\end{matrix} \right.$$ Обратите внимание, что корреляционная матрица симметрична, поскольку корреляция симметрична, т. Е. `M (i, j) = M (j, i)`. Давайте возьмем наш простой пример из предыдущего раздела и посмотрим, как использовать `corrcoef ()` с `numpy`.

Во-первых, давайте импортируем numpy вместе с pyplot из Matplotlib. Позже мы будем использовать Matplotlib для визуализации корреляции:

 import numpy as np 
 import matplotlib.pyplot as plt 

Мы будем использовать те же значения из ручного примера, что и раньше. x_simple это в x_simple и вычислим корреляционную матрицу:

 x_simple = np.array([-2, -1, 0, 1, 2]) 
 y_simple = np.array([4, 1, 3, 2, 0]) 
 my_rho = np.corrcoef(x_simple, y_simple) 
 
 print(my_rho) 

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

 [[ 1. -0.7] 
 [-0.7 1. ]] 

Примеры положительной и отрицательной корреляции

Давайте визуализируем коэффициенты корреляции для нескольких отношений. Во-первых, у нас будет полная положительная (+1) и полная отрицательная (-1) корреляция между двумя переменными. Затем мы сгенерируем две случайные величины, поэтому коэффициент корреляции обязательно должен быть близок к нулю, если случайность случайно не имеет некоторой корреляции, что очень маловероятно.

Мы будем использовать seed чтобы этот пример можно было RandomState при вызове RandomState из Numpy:

 seed = 13 
 rand = np.random.RandomState(seed) 
 
 x = rand.uniform(0,1,100) 
 x = np.vstack((x,x*2+1)) 
 x = np.vstack((x,-x[0,]*2+1)) 
 x = np.vstack((x,rand.normal(1,3,100))) 

Первый rand.uniform() генерирует случайное равномерное распределение:

 [7.77702411e-01 2.37541220e-01 8.24278533e-01 9.65749198e-01 
 9.72601114e-01 4.53449247e-01 6.09042463e-01 7.75526515e-01 
 6.41613345e-01 7.22018230e-01 3.50365241e-02 2.98449471e-01 
 5.85124919e-02 8.57060943e-01 3.72854028e-01 6.79847952e-01 
 2.56279949e-01 3.47581215e-01 9.41277008e-03 3.58333783e-01 
 9.49094182e-01 2.17899009e-01 3.19391366e-01 9.17772386e-01 
 3.19036664e-02 6.50845370e-02 6.29828999e-01 8.73813443e-01 
 8.71573230e-03 7.46577237e-01 8.12841171e-01 7.57174462e-02 
 6.56455335e-01 5.09262200e-01 4.79883391e-01 9.55574145e-01 
 1.20335695e-05 2.46978701e-01 7.12232678e-01 3.24582050e-01 
 2.76996356e-01 6.95445453e-01 9.18551748e-01 2.44475702e-01 
 4.58085817e-01 2.52992683e-01 3.79333291e-01 6.04538829e-01 
 7.72378760e-01 6.79174968e-02 6.86085079e-01 5.48260097e-01 
 1.37986053e-01 9.87532192e-02 2.45559105e-01 1.51786663e-01 
 9.25994479e-01 6.80105016e-01 2.37658922e-01 5.68885253e-01 
 5.56632051e-01 7.27372109e-02 8.39708510e-01 4.05319493e-01 
 1.44870989e-01 1.90920059e-01 4.90640137e-01 7.12024374e-01 
 9.84938458e-01 8.74786502e-01 4.99041684e-01 1.06779994e-01 
 9.13212807e-01 3.64915961e-01 2.26587877e-01 8.72431862e-01 
 1.36358352e-01 2.36380160e-01 5.95399245e-01 5.63922609e-01 
 9.58934732e-01 4.53239333e-01 1.28958075e-01 7.60567677e-01 
 2.01634075e-01 1.75729863e-01 4.37118013e-01 3.40260803e-01 
 9.67253109e-01 1.43026077e-01 8.44558533e-01 6.69406140e-01 
 1.09304908e-01 8.82535400e-02 9.66462041e-01 1.94297485e-01 
 8.19000600e-02 2.69384695e-01 6.50130518e-01 5.46777245e-01] 

Затем мы можем вызвать vstack() чтобы вертикально складывать в него другие массивы. Таким образом, мы можем поместить кучу переменных, подобных приведенным выше, в одну x и обращаться к ним последовательно.

После первого равномерного распределения мы сложили несколько наборов переменных по вертикали - второй имеет полную положительную связь с первым, третий имеет полную отрицательную корреляцию с первым, а четвертый полностью случайный, поэтому он должен иметь корреляцию ~ 0.

Когда у нас есть одна x , мы можем вычислить корреляцию для каждого из элементов в вертикальном стеке, передав ее одну в np.corrcoef() :

 rho = np.corrcoef(x) 
 
 fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(12, 3)) 
 for i in [0,1,2]: 
 ax[i].scatter(x[0,],x[1+i,]) 
 ax[i].title.set_text('Correlation = ' + "{:.2f}".format(rho[0,i+1])) 
 ax[i].set(xlabel='x',ylabel='y') 
 fig.subplots_adjust(wspace=.4) 
 plt.show() 

коэффициент корреляцииПирсона{.ezlazyload}

Понимание изменений коэффициента корреляции Пирсона

Чтобы увидеть, как изменяется коэффициент корреляции при изменении отношения между двумя переменными, давайте добавим некоторый случайный шум к x сгенерированной в предыдущем разделе, и повторно запустим код.

В этом примере мы будем медленно добавлять различные степени шума к графикам корреляции и вычислять коэффициенты корреляции на каждом шаге:

 fig, ax = plt.subplots(nrows=2, ncols=4, figsize=(15, 8)) 
 
 for noise, i in zip([0.05,0.2,0.8,2],[0,1,2,3]): 
 # Add noise 
 x_with_noise = x+rand.normal(0,noise,x.shape) 
 
 # Compute correlation 
 rho_noise = np.corrcoef(x_with_noise) 
 
 # Plot column wise. Positive correlation in row 0 and negative in row 1 
 ax[0,i].scatter(x_with_noise[0,],x_with_noise[1,],color='magenta') 
 ax[1,i].scatter(x_with_noise[0,],x_with_noise[2,],color='green') 
 ax[0,i].title.set_text('Correlation = ' + "{:.2f}".format(rho_noise[0,1]) 
 + '\n Noise = ' + "{:.2f}".format(noise) ) 
 ax[1,i].title.set_text('Correlation = ' + "{:.2f}".format(rho_noise[0,2]) 
 + '\n Noise = ' + "{:.2f}".format(noise)) 
 ax[0,i].set(xlabel='x',ylabel='y') 
 ax[1,i].set(xlabel='x',ylabel='y') 
 
 fig.subplots_adjust(wspace=0.3,hspace=0.4) 
 plt.show() 

коэффициент корреляции Пирсона сшумом{.ezlazyload}

Распространенная ловушка: ассоциации без корреляции

Существует распространенное заблуждение, что нулевая корреляция не подразумевает никакой связи. Поясним, что корреляция строго измеряет линейную связь между двумя переменными.

В приведенных ниже примерах показаны переменные, которые нелинейно связаны друг с другом, но имеют нулевую корреляцию.

Последний пример (y = e ^x^ ) имеет коэффициент корреляции около 0,52, что опять же не является отражением истинной связи между двумя переменными:

 # Create a data matrix 
 x_nonlinear = np.linspace(-10,10,100) 
 x_nonlinear = np.vstack((x_nonlinear,x_nonlinear*x_nonlinear)) 
 x_nonlinear = np.vstack((x_nonlinear,-x_nonlinear[0,]**2)) 
 x_nonlinear = np.vstack((x_nonlinear,x_nonlinear[0,]**4)) 
 x_nonlinear = np.vstack((x_nonlinear,np.log(x_nonlinear[0,]**2+1))) 
 x_nonlinear = np.vstack((x_nonlinear,np.exp(x_nonlinear[0,]))) 
 
 # Compute the correlation 
 rho_nonlinear = np.corrcoef(x_nonlinear) 
 
 # Plot the data 
 fig, ax = plt.subplots(nrows=1, ncols=5, figsize=(16, 3)) 
 title = ['$y=x^2$','$y=-x^2$','$y=x^4$','$y=\log(x^2+1)$','$y=\exp(x)$'] 
 for i in [0,1,2,3,4]: 
 ax[i].scatter(x_nonlinear[0,],x_nonlinear[1+i,],color='cyan') 
 ax[i].title.set_text(title[i] + '\n' + 
 'Correlation = ' + "{:.2f}".format(rho_nonlinear[0,i+1])) 
 ax[i].set(xlabel='x',ylabel='y') 
 fig.subplots_adjust(wspace=.4) 
 plt.show() 

коэффициент корреляции Пирсона против переменнойассоциации{.ezlazyload}

Выводы

В этой статье мы обсудили коэффициент корреляции Пирсона. Мы использовали метод corrcoef() из numpy для вычисления его значения.

Если случайные величины имеют высокие линейные ассоциации, то их коэффициент корреляции близок к +1 или -1. С другой стороны, статистически независимые переменные имеют коэффициенты корреляции, близкие к нулю.

Мы также продемонстрировали, что нелинейные ассоциации могут иметь нулевой или близкий к нулю коэффициент корреляции, подразумевая, что переменные, имеющие высокие ассоциации, могут не иметь высокого значения коэффициента корреляции Пирсона.

comments powered by Disqus