Расчет корреляции Пирсона и значимости в Python - PullRequest
171 голосов
/ 16 октября 2010

Я ищу функцию, которая принимает в качестве входных данных два списка и возвращает корреляцию Пирсона и значение корреляции.

Ответы [ 16 ]

189 голосов
/ 16 октября 2010

Вы можете взглянуть на scipy.stats:

from pydoc import help
from scipy.stats.stats import pearsonr
help(pearsonr)

>>>
Help on function pearsonr in module scipy.stats.stats:

pearsonr(x, y)
 Calculates a Pearson correlation coefficient and the p-value for testing
 non-correlation.

 The Pearson correlation coefficient measures the linear relationship
 between two datasets. Strictly speaking, Pearson's correlation requires
 that each dataset be normally distributed. Like other correlation
 coefficients, this one varies between -1 and +1 with 0 implying no
 correlation. Correlations of -1 or +1 imply an exact linear
 relationship. Positive correlations imply that as x increases, so does
 y. Negative correlations imply that as x increases, y decreases.

 The p-value roughly indicates the probability of an uncorrelated system
 producing datasets that have a Pearson correlation at least as extreme
 as the one computed from these datasets. The p-values are not entirely
 reliable but are probably reasonable for datasets larger than 500 or so.

 Parameters
 ----------
 x : 1D array
 y : 1D array the same length as x

 Returns
 -------
 (Pearson's correlation coefficient,
  2-tailed p-value)

 References
 ----------
 http://www.statsoft.com/textbook/glosp.html#Pearson%20Correlation
100 голосов
/ 16 апреля 2013

Корреляция Пирсона может быть рассчитана с помощью numpy's corrcoef.

import numpy
numpy.corrcoef(list1, list2)[0, 1]
49 голосов
/ 21 ноября 2015

Альтернативой может быть собственная функция scipy из linregress , которая вычисляет:

Наклон: наклон линии регрессии

Перехват: перехват регрессииline

r-значение: коэффициент корреляции

p-значение: двустороннее p-значение для проверки гипотезы, нулевая гипотеза которой состоит в том, что наклон равен нулю

stderr:Стандартная ошибка оценки

А вот пример:

a = [15, 12, 8, 8, 7, 7, 7, 6, 5, 3]
b = [10, 25, 17, 11, 13, 17, 20, 13, 9, 15]
from scipy.stats import linregress
linregress(a, b)

вернет вам:

LinregressResult(slope=0.20833333333333337, intercept=13.375, rvalue=0.14499815458068521, pvalue=0.68940144811669501, stderr=0.50261704627083648)
35 голосов
/ 19 апреля 2011

Если вам не хочется устанавливать scipy, я воспользовался этим быстрым взломом, слегка измененным с Программирование Коллективного Разума :

(отредактировано для корректности.)

from itertools import imap

def pearsonr(x, y):
  # Assume len(x) == len(y)
  n = len(x)
  sum_x = float(sum(x))
  sum_y = float(sum(y))
  sum_x_sq = sum(map(lambda x: pow(x, 2), x))
  sum_y_sq = sum(map(lambda x: pow(x, 2), y))
  psum = sum(imap(lambda x, y: x * y, x, y))
  num = psum - (sum_x * sum_y/n)
  den = pow((sum_x_sq - pow(sum_x, 2) / n) * (sum_y_sq - pow(sum_y, 2) / n), 0.5)
  if den == 0: return 0
  return num / den
30 голосов
/ 29 октября 2011

Следующий код является прямой интерпретацией определения :

import math

def average(x):
    assert len(x) > 0
    return float(sum(x)) / len(x)

def pearson_def(x, y):
    assert len(x) == len(y)
    n = len(x)
    assert n > 0
    avg_x = average(x)
    avg_y = average(y)
    diffprod = 0
    xdiff2 = 0
    ydiff2 = 0
    for idx in range(n):
        xdiff = x[idx] - avg_x
        ydiff = y[idx] - avg_y
        diffprod += xdiff * ydiff
        xdiff2 += xdiff * xdiff
        ydiff2 += ydiff * ydiff

    return diffprod / math.sqrt(xdiff2 * ydiff2)

Тест:

print pearson_def([1,2,3], [1,5,7])

возвращает

0.981980506062

Это согласуется с Excel, этот калькулятор , SciPy (также NumPy ), который возвращает 0,981980506 и 0,9819805060619657 и 0,98198050606196574, соответственно.

R

> cor( c(1,2,3), c(1,5,7))
[1] 0.9819805

РЕДАКТИРОВАТЬ : исправлена ​​ошибка, указанная комментатором.

24 голосов
/ 29 января 2017

Вы можете сделать это также с помощью pandas.DataFrame.corr:

import pandas as pd
a = [[1, 2, 3],
     [5, 6, 9],
     [5, 6, 11],
     [5, 6, 13],
     [5, 3, 13]]
df = pd.DataFrame(data=a)
df.corr()

Это дает

          0         1         2
0  1.000000  0.745601  0.916579
1  0.745601  1.000000  0.544248
2  0.916579  0.544248  1.000000
12 голосов
/ 30 июня 2013

Вместо того, чтобы полагаться на numpy / scipy, я думаю, что мой ответ должен быть проще всего кодировать и понять шаги при расчете коэффициента корреляции Пирсона (PCC).Значение PCC в основном показывает, насколько сильно коррелирует две переменные / списки.Важно отметить, что значение PCC составляет от -1 до 1 .Значение от 0 до 1 обозначает положительную корреляцию.Значение 0 = наибольшее отклонение (без какой-либо корреляции).Значение от -1 до 0 обозначает отрицательную корреляцию.

7 голосов
/ 31 октября 2013

Хм, многие из этих ответов имеют длинный и трудный для чтения код ...

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

import numpy as np
def pcc(X, Y):
   ''' Compute Pearson Correlation Coefficient. '''
   # Normalise X and Y
   X -= X.mean(0)
   Y -= Y.mean(0)
   # Standardise X and Y
   X /= X.std(0)
   Y /= Y.std(0)
   # Compute mean product
   return np.mean(X*Y)

# Using it on a random example
from random import random
X = np.array([random() for x in xrange(100)])
Y = np.array([random() for x in xrange(100)])
pcc(X, Y)
6 голосов
/ 03 марта 2015

Это реализация корреляционной функции Пирсона с использованием numpy:


def corr(data1, data2):
    "data1 & data2 should be numpy arrays."
    mean1 = data1.mean() 
    mean2 = data2.mean()
    std1 = data1.std()
    std2 = data2.std()

#     corr = ((data1-mean1)*(data2-mean2)).mean()/(std1*std2)
    corr = ((data1*data2).mean()-mean1*mean2)/(std1*std2)
    return corr

5 голосов
/ 09 сентября 2018

Расчет коэффициента Пирсона с использованием панд в python: я бы предложил попробовать этот подход, поскольку ваши данные содержат списки.Будет легко взаимодействовать с вашими данными и манипулировать ими из консоли, поскольку вы сможете визуализировать свою структуру данных и обновлять ее по своему желанию.Вы также можете экспортировать набор данных, сохранить его и добавить новые данные из консоли Python для последующего анализа.Этот код проще и содержит меньше строк кода.Я предполагаю, что вам нужно несколько быстрых строк кода для проверки ваших данных для дальнейшего анализа

Пример:

data = {'list 1':[2,4,6,8],'list 2':[4,16,36,64]}

import pandas as pd #To Convert your lists to pandas data frames convert your lists into pandas dataframes

df = pd.DataFrame(data, columns = ['list 1','list 2'])

from scipy import stats # For in-built method to get PCC

pearson_coef, p_value = stats.pearsonr(df["list 1"], df["list 2"]) #define the columns to perform calculations on
print("Pearson Correlation Coefficient: ", pearson_coef, "and a P-value of:", p_value) # Results 

Однако вы не опубликовали свои данные для меня, чтобы увидеть размернабор данных или преобразования, которые могут потребоваться перед анализом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...