मैं एक ऐसे फ़ंक्शन की तलाश में हूं जो इनपुट दो सूचियों के रूप में लेता है, और पियर्सन सहसंबंध , और सहसंबंध का महत्व देता है।
मैं एक ऐसे फ़ंक्शन की तलाश में हूं जो इनपुट दो सूचियों के रूप में लेता है, और पियर्सन सहसंबंध , और सहसंबंध का महत्व देता है।
जवाबों:
आप पर एक नज़र डाल सकते हैं 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
Pearson सहसंबंध की गणना सुन्न के साथ की जा सकती है corrcoef
।
import numpy
numpy.corrcoef(list1, list2)[0, 1]
एक विकल्प वंशानुक्रम से एक देशी घिनौना कार्य हो सकता है जो गणना करता है:
ढलान: प्रतिगमन रेखा का ढलान
अवरोधन: प्रतिगमन रेखा का अवरोधन
r- मूल्य: सहसंबंध गुणांक
पी-मूल्य: एक परिकल्पना परीक्षण के लिए दो-तरफा पी-मूल्य जिसका शून्य परिकल्पना है कि ढलान शून्य है
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)
lineregress(two_row_df)
यदि आपको डरपोक स्थापित करने का मन नहीं है, तो मैंने इस त्वरित हैक का उपयोग किया है, प्रोग्रामिंग कलेक्टिव इंटेलिजेंस से थोड़ा संशोधित :
(शुद्धता के लिए संपादित।)
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'
परnum = psum - (sum_x * sum_y/n)
निम्नलिखित कोड परिभाषा की एक सीधी-अप व्याख्या है :
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
यह एक्सेल, इस कैलकुलेटर , SciPy (भी NumPy ) से सहमत है , जो क्रमशः 0.981980506 और 0.9819805060619657, और 0.98198050606196574 पर वापस आते हैं।
आर :
> cor( c(1,2,3), c(1,5,7))
[1] 0.9819805
संपादित करें : एक टिप्पणीकार द्वारा इंगित बग को फिक्स्ड बग।
sum(x) / len(x)
आप ints विभाजित, तैरता नहीं। तो sum([1,5,7]) / len([1,5,7]) = 13 / 3 = 4
, पूर्णांक विभाजन के अनुसार (जब आप चाहते हैं 13. / 3. = 4.33...
)। इसे ठीक करने के लिए इस लाइन को फिर से float(sum(x)) / float(len(x))
लिखें (एक फ्लोट पर्याप्त है, जैसा कि पायथन इसे स्वचालित रूप से परिवर्तित करता है)।
आप इसके साथ कर सकते हैं 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
सुन्न / डरावना पर भरोसा करने के बजाय, मुझे लगता है कि मेरे उत्तर को कोड करने के लिए सबसे आसान होना चाहिए और पियर्सन सहसंबंध गुणांक (पीसीसी) की गणना करने के चरणों को समझना चाहिए ।
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)
महत्व पीसीसी की आप को दिखाने के लिए कैसे मूल रूप से है दृढ़ता से सहसंबद्ध दो चर / सूची नहीं है। यह ध्यान रखना महत्वपूर्ण है कि पीसीसी मूल्य -1 से 1 तक है । 0 से 1 के बीच का मान एक सकारात्मक सहसंबंध को दर्शाता है। मान 0 = उच्चतम भिन्नता (कोई सहसंबंध जो भी हो)। -1 से 0 के बीच का मान नकारात्मक सहसंबंध को दर्शाता है।
sum
फ़ंक्शन होता है।
पाइथन में पंडों के उपयोग से पियर्सन गुणांक की गणना: मैं इस दृष्टिकोण को आजमाना चाहूंगा क्योंकि आपके डेटा में सूचियाँ हैं। अपने डेटा के साथ सहभागिता करना और इसे कंसोल से हेरफेर करना आसान होगा क्योंकि आप अपनी डेटा संरचना की कल्पना कर सकते हैं और इसे अपनी इच्छानुसार अपडेट कर सकते हैं। आप डेटा सेट को निर्यात भी कर सकते हैं और इसे बचा सकते हैं और बाद के विश्लेषण के लिए अजगर कंसोल से नए डेटा को जोड़ सकते हैं। यह कोड सरल है और इसमें कोड की कम लाइनें हैं। मैं मान रहा हूं कि आपको आगे के विश्लेषण के लिए अपने डेटा को स्क्रीन करने के लिए कोड की कुछ त्वरित लाइनों की आवश्यकता होगी
उदाहरण:
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
हालाँकि, आपने डेटा सेट या विश्लेषण से पहले आवश्यक परिवर्तनों को देखने के लिए अपना डेटा मेरे लिए पोस्ट नहीं किया था।
हम्म, इन प्रतिक्रियाओं में से कई लंबे और कोड पढ़ने के लिए कठिन है ...
जब मैं सरणियों के साथ काम कर रहा हूँ तो इसके निफ्टी फीचर्स के साथ 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)
यह Pearson सहसंबंध समारोह के कार्यान्वयन का उपयोग कर रहा है:
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
यहाँ mkh के उत्तर पर एक संस्करण है जो इसके मुकाबले बहुत तेज़ चलता है, और scipy.stats.pearsonr, 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)
यहाँ विरल वेक्टर के आधार पर पीयरसन सहसंबंध के लिए एक कार्यान्वयन है। यहां के वैक्टरों को (सूचकांक, मूल्य) के रूप में व्यक्त किए गए टुपल्स की सूची के रूप में व्यक्त किया जाता है। दो विरल वैक्टर अलग-अलग लंबाई के हो सकते हैं लेकिन सभी वेक्टर आकार में समान होना चाहिए। यह टेक्स्ट माइनिंग एप्लिकेशन के लिए उपयोगी है जहां अधिकांश विशेषताओं के शब्दों के बैग होने के कारण वेक्टर का आकार बहुत बड़ा है और इसलिए आमतौर पर विरल वैक्टर का उपयोग करके गणना की जाती है।
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)
इकाई परीक्षण:
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)
मेरे पास इसके लिए एक बहुत ही सरल और समझने वाला समाधान है। समान लंबाई के दो सरणियों के लिए, पीयरसन गुणांक को आसानी से निम्नानुसार गणना की जा सकती है:
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
आप आश्चर्यचकित हो सकते हैं कि किसी विशेष दिशा (नकारात्मक या सकारात्मक सहसंबंध) में सहसंबंध की तलाश के संदर्भ में अपनी संभावना की व्याख्या कैसे करें। यहां एक फ़ंक्शन है जिसकी सहायता से मैंने लिखा है। यह सही भी हो सकता है!
यह जानकारी पर आधारित है जिसे मैंने http://www.vassarstats.net/rsig.html और http://en.wikipedia.org/wiki/Student%27s_t_distribution से प्राप्त किया है , जो यहां पोस्ट किए गए अन्य उत्तरों के लिए धन्यवाद है।
# 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)
आप इस लेख पर एक नज़र डाल सकते हैं। यह पांडा फॉरेक्स लाइब्रेरी (पायथन के लिए) का उपयोग करके कई फाइलों से ऐतिहासिक विदेशी मुद्रा मुद्रा जोड़े के आंकड़ों के आधार पर सहसंबंध की गणना के लिए एक अच्छी तरह से प्रलेखित उदाहरण है, और फिर सीबॉर्न लाइब्रेरी का उपयोग करके हीटमैप प्लॉट तैयार करता है।
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