Вступление
Эта статья представляет собой введение в коэффициент корреляции
Пирсона , его вычисление вручную и вычисление с помощью модуля 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. С другой стороны, статистически независимые переменные имеют коэффициенты корреляции, близкие к нулю.
Мы также продемонстрировали, что нелинейные ассоциации могут иметь нулевой или близкий к нулю коэффициент корреляции, подразумевая, что переменные, имеющие высокие ассоциации, могут не иметь высокого значения коэффициента корреляции Пирсона.