Saya mencari fungsi yang mengambil input dua daftar, dan mengembalikan korelasi Pearson , dan pentingnya korelasi.
Saya mencari fungsi yang mengambil input dua daftar, dan mengembalikan korelasi Pearson , dan pentingnya korelasi.
Jawaban:
Anda dapat melihat 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
Korelasi Pearson dapat dihitung dengan numpy corrcoef
.
import numpy
numpy.corrcoef(list1, list2)[0, 1]
Alternatif dapat berupa fungsi scipy asli dari linregress yang menghitung:
slope: kemiringan garis regresi
mencegat: mencegat garis regresi
nilai r: koefisien korelasi
p-value: p-value dua sisi untuk uji hipotesis yang hipotesis nolnya adalah kemiringan nol
stderr: Kesalahan standar estimasi
Dan ini sebuah contoh:
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)
akan mengembalikan Anda:
LinregressResult(slope=0.20833333333333337, intercept=13.375, rvalue=0.14499815458068521, pvalue=0.68940144811669501, stderr=0.50261704627083648)
lineregress(two_row_df)
Jika Anda merasa tidak ingin menginstal scipy, saya telah menggunakan hack cepat ini, sedikit dimodifikasi dari Programming Collective Intelligence :
(Diedit untuk kebenaran.)
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
TypeError: unsupported operand type(s) for -: 'itertools.imap' and 'float'
atnum = psum - (sum_x * sum_y/n)
Kode berikut adalah interpretasi langsung dari definisi :
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)
Uji:
print pearson_def([1,2,3], [1,5,7])
kembali
0.981980506062
Ini setuju dengan Excel, kalkulator ini , SciPy (juga NumPy ), yang mengembalikan 0,981980506 dan 0,9819805060619657, dan 0,98198050606196574, masing-masing.
R :
> cor( c(1,2,3), c(1,5,7))
[1] 0.9819805
EDIT : Memperbaiki bug yang ditunjukkan oleh komentator.
sum(x) / len(x)
Anda membagi ints, bukan mengapung. Jadi sum([1,5,7]) / len([1,5,7]) = 13 / 3 = 4
, menurut pembagian integer (padahal Anda mau 13. / 3. = 4.33...
). Untuk memperbaikinya, tulis ulang baris ini sebagai float(sum(x)) / float(len(x))
(satu float sudah mencukupi, seperti Python yang mengubahnya secara otomatis).
Anda dapat melakukannya dengan 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()
Ini memberi
0 1 2
0 1.000000 0.745601 0.916579
1 0.745601 1.000000 0.544248
2 0.916579 0.544248 1.000000
Daripada mengandalkan numpy / scipy, saya pikir jawaban saya harus yang paling mudah untuk kode dan memahami langkah-langkah dalam menghitung Koefisien Korelasi Pearson (PCC).
import math
# calculates the mean
def mean(x):
sum = 0.0
for i in x:
sum += i
return sum / len(x)
# calculates the sample standard deviation
def sampleStandardDeviation(x):
sumv = 0.0
for i in x:
sumv += (i - mean(x))**2
return math.sqrt(sumv/(len(x)-1))
# calculates the PCC using both the 2 functions above
def pearson(x,y):
scorex = []
scorey = []
for i in x:
scorex.append((i - mean(x))/sampleStandardDeviation(x))
for j in y:
scorey.append((j - mean(y))/sampleStandardDeviation(y))
# multiplies both lists together into 1 list (hence zip) and sums the whole list
return (sum([i*j for i,j in zip(scorex,scorey)]))/(len(x)-1)
The signifikansi dari PCC pada dasarnya adalah untuk menunjukkan kepada Anda bagaimana sangat berkorelasi dua variabel / daftar yang. Penting untuk dicatat bahwa nilai PCC berkisar dari -1 hingga 1 . Nilai antara 0 hingga 1 menunjukkan korelasi positif. Nilai 0 = variasi tertinggi (tidak ada korelasi apa pun). Nilai antara -1 hingga 0 menunjukkan korelasi negatif.
sum
fungsi bawaan .
Perhitungan koefisien Pearson menggunakan panda dalam python: Saya sarankan mencoba pendekatan ini karena data Anda berisi daftar. Akan mudah berinteraksi dengan data Anda dan memanipulasinya dari konsol karena Anda dapat memvisualisasikan struktur data Anda dan memperbaruinya sesuai keinginan. Anda juga dapat mengekspor kumpulan data dan menyimpannya dan menambahkan data baru dari konsol python untuk analisis nanti. Kode ini lebih sederhana dan mengandung lebih sedikit baris kode. Saya mengasumsikan Anda memerlukan beberapa baris kode cepat untuk menyaring data Anda untuk analisis lebih lanjut
Contoh:
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
Namun, Anda tidak memposting data Anda untuk saya untuk melihat ukuran kumpulan data atau transformasi yang mungkin diperlukan sebelum analisis.
Hmm, banyak dari tanggapan ini yang panjang dan sulit dibaca kode ...
Saya sarankan menggunakan numpy dengan fitur-fiturnya yang bagus ketika bekerja dengan array:
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)
Ini adalah implementasi fungsi Korelasi Pearson menggunakan 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
Berikut varian jawaban mkh yang berjalan lebih cepat daripada itu, dan scipy.stats.pearsonr, menggunakan numba.
import numba
@numba.jit
def corr(data1, data2):
M = data1.size
sum1 = 0.
sum2 = 0.
for i in range(M):
sum1 += data1[i]
sum2 += data2[i]
mean1 = sum1 / M
mean2 = sum2 / M
var_sum1 = 0.
var_sum2 = 0.
cross_sum = 0.
for i in range(M):
var_sum1 += (data1[i] - mean1) ** 2
var_sum2 += (data2[i] - mean2) ** 2
cross_sum += (data1[i] * data2[i])
std1 = (var_sum1 / M) ** .5
std2 = (var_sum2 / M) ** .5
cross_mean = cross_sum / M
return (cross_mean - mean1 * mean2) / (std1 * std2)
Berikut ini adalah implementasi untuk korelasi pearson berdasarkan vektor jarang. Vektor di sini dinyatakan sebagai daftar tupel yang dinyatakan sebagai (indeks, nilai). Dua vektor jarang dapat memiliki panjang yang berbeda tetapi pada semua ukuran vektor harus sama. Ini berguna untuk aplikasi penambangan teks di mana ukuran vektor sangat besar karena sebagian besar fitur menjadi kantong kata dan karenanya perhitungan biasanya dilakukan menggunakan vektor jarang.
def get_pearson_corelation(self, first_feature_vector=[], second_feature_vector=[], length_of_featureset=0):
indexed_feature_dict = {}
if first_feature_vector == [] or second_feature_vector == [] or length_of_featureset == 0:
raise ValueError("Empty feature vectors or zero length of featureset in get_pearson_corelation")
sum_a = sum(value for index, value in first_feature_vector)
sum_b = sum(value for index, value in second_feature_vector)
avg_a = float(sum_a) / length_of_featureset
avg_b = float(sum_b) / length_of_featureset
mean_sq_error_a = sqrt((sum((value - avg_a) ** 2 for index, value in first_feature_vector)) + ((
length_of_featureset - len(first_feature_vector)) * ((0 - avg_a) ** 2)))
mean_sq_error_b = sqrt((sum((value - avg_b) ** 2 for index, value in second_feature_vector)) + ((
length_of_featureset - len(second_feature_vector)) * ((0 - avg_b) ** 2)))
covariance_a_b = 0
#calculate covariance for the sparse vectors
for tuple in first_feature_vector:
if len(tuple) != 2:
raise ValueError("Invalid feature frequency tuple in featureVector: %s") % (tuple,)
indexed_feature_dict[tuple[0]] = tuple[1]
count_of_features = 0
for tuple in second_feature_vector:
count_of_features += 1
if len(tuple) != 2:
raise ValueError("Invalid feature frequency tuple in featureVector: %s") % (tuple,)
if tuple[0] in indexed_feature_dict:
covariance_a_b += ((indexed_feature_dict[tuple[0]] - avg_a) * (tuple[1] - avg_b))
del (indexed_feature_dict[tuple[0]])
else:
covariance_a_b += (0 - avg_a) * (tuple[1] - avg_b)
for index in indexed_feature_dict:
count_of_features += 1
covariance_a_b += (indexed_feature_dict[index] - avg_a) * (0 - avg_b)
#adjust covariance with rest of vector with 0 value
covariance_a_b += (length_of_featureset - count_of_features) * -avg_a * -avg_b
if mean_sq_error_a == 0 or mean_sq_error_b == 0:
return -1
else:
return float(covariance_a_b) / (mean_sq_error_a * mean_sq_error_b)
Tes unit:
def test_get_get_pearson_corelation(self):
vector_a = [(1, 1), (2, 2), (3, 3)]
vector_b = [(1, 1), (2, 5), (3, 7)]
self.assertAlmostEquals(self.sim_calculator.get_pearson_corelation(vector_a, vector_b, 3), 0.981980506062, 3, None, None)
vector_a = [(1, 1), (2, 2), (3, 3)]
vector_b = [(1, 1), (2, 5), (3, 7), (4, 14)]
self.assertAlmostEquals(self.sim_calculator.get_pearson_corelation(vector_a, vector_b, 5), -0.0137089240555, 3, None, None)
Saya punya solusi yang sangat sederhana dan mudah dipahami untuk ini. Untuk dua array dengan panjang yang sama, koefisien Pearson dapat dengan mudah dihitung sebagai berikut:
def manual_pearson(a,b):
"""
Accepts two arrays of equal length, and computes correlation coefficient.
Numerator is the sum of product of (a - a_avg) and (b - b_avg),
while denominator is the product of a_std and b_std multiplied by
length of array.
"""
a_avg, b_avg = np.average(a), np.average(b)
a_stdev, b_stdev = np.std(a), np.std(b)
n = len(a)
denominator = a_stdev * b_stdev * n
numerator = np.sum(np.multiply(a-a_avg, b-b_avg))
p_coef = numerator/denominator
return p_coef
Anda mungkin bertanya-tanya bagaimana menafsirkan probabilitas Anda dalam konteks mencari korelasi dalam arah tertentu (korelasi negatif atau positif.) Berikut adalah fungsi yang saya tulis untuk membantu hal itu. Bahkan mungkin benar!
Ini berdasarkan info yang saya peroleh dari http://www.vassarstats.net/rsig.html dan http://en.wikipedia.org/wiki/Student%27s_t_distribution , terima kasih atas jawaban lain yang diposting di sini.
# Given (possibly random) variables, X and Y, and a correlation direction,
# returns:
# (r, p),
# where r is the Pearson correlation coefficient, and p is the probability
# that there is no correlation in the given direction.
#
# direction:
# if positive, p is the probability that there is no positive correlation in
# the population sampled by X and Y
# if negative, p is the probability that there is no negative correlation
# if 0, p is the probability that there is no correlation in either direction
def probabilityNotCorrelated(X, Y, direction=0):
x = len(X)
if x != len(Y):
raise ValueError("variables not same len: " + str(x) + ", and " + \
str(len(Y)))
if x < 6:
raise ValueError("must have at least 6 samples, but have " + str(x))
(corr, prb_2_tail) = stats.pearsonr(X, Y)
if not direction:
return (corr, prb_2_tail)
prb_1_tail = prb_2_tail / 2
if corr * direction > 0:
return (corr, prb_1_tail)
return (corr, 1 - prb_1_tail)
Anda dapat melihat artikel ini. Ini adalah contoh yang terdokumentasi dengan baik untuk menghitung korelasi berdasarkan data pasangan mata uang forex historis dari beberapa file menggunakan panda library (untuk Python), dan kemudian menghasilkan plot peta panas menggunakan perpustakaan seaborn.
http://www.tradinggeeks.net/2015/08/calculating-correlation-in-python/
def pearson(x,y):
n=len(x)
vals=range(n)
sumx=sum([float(x[i]) for i in vals])
sumy=sum([float(y[i]) for i in vals])
sumxSq=sum([x[i]**2.0 for i in vals])
sumySq=sum([y[i]**2.0 for i in vals])
pSum=sum([x[i]*y[i] for i in vals])
# Calculating Pearson correlation
num=pSum-(sumx*sumy/n)
den=((sumxSq-pow(sumx,2)/n)*(sumySq-pow(sumy,2)/n))**.5
if den==0: return 0
r=num/den
return r