sirve regresion que prediccion para lineal datos correlacion coeficiente coefficient coefcorr analisis ajuste python numpy statistics scipy

regresion - prediccion de datos python



Cálculo de la correlación de Pearson y su significado en Python (14)

Aquí hay una implementación para la correlación de pearson basada en vector disperso. Los vectores aquí se expresan como una lista de tuplas expresadas como (índice, valor). Los dos vectores dispersos pueden ser de diferente longitud pero sobre todo el tamaño del vector tendrá que ser el mismo. Esto es útil para aplicaciones de minería de textos en las que el tamaño del vector es extremadamente grande debido a que la mayoría de las características son una bolsa de palabras y, por lo tanto, los cálculos se realizan generalmente utilizando vectores dispersos.

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)

Pruebas unitarias:

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)

Estoy buscando una función que tome como entrada dos listas, y devuelve la correlación de Pearson , y la importancia de la correlación.


Aquí hay una variante de la respuesta de mkh que corre mucho más rápido que ella, y scipy.stats.pearsonr, usando 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)


El siguiente código es una interpretación directa de la definició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)

Prueba:

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

devoluciones

0.981980506062

Esto concuerda con Excel, esta calculadora , SciPy (también corrcoef ), que devuelve 0.981980506 y 0.9819805060619657, y 0.98198050606196574, respectivamente.

R :

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

EDITAR : corrigió un error señalado por un comentarista.


En lugar de confiar en numpy / scipy, creo que mi respuesta debería ser la más fácil de codificar y comprender los pasos para calcular el Coeficiente de correlación de 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)

La importancia de PCC es básicamente mostrarle qué tan fuertemente correlacionadas están las dos variables / listas. Es importante tener en cuenta que el valor de PCC varía de -1 a 1 . Un valor entre 0 y 1 denota una correlación positiva. Valor de 0 = variación más alta (sin correlación alguna). Un valor entre -1 a 0 denota una correlación negativa.


Esta es una implementación de la función de correlación de Pearson usando 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


Hmm, muchas de estas respuestas tienen un código largo y difícil de leer ...

Sugeriría usar numpy con sus ingeniosas funciones cuando trabaje con matrices:

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)


La correlación de Pearson puede calcularse con la corrcoef de corrcoef .

import numpy numpy.corrcoef(list1, list2)[0, 1]


Puede preguntarse cómo interpretar su probabilidad en el contexto de buscar una correlación en una dirección particular (correlación negativa o positiva). Aquí hay una función que escribí para ayudar con eso. ¡Incluso podría ser correcto!

Se basa en la información que obtuve de http://www.vassarstats.net/rsig.html y http://en.wikipedia.org/wiki/Student%27s_t_distribution , gracias a otras respuestas publicadas aquí.

# 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)


Puedes echar un vistazo a este artículo. Este es un ejemplo bien documentado para calcular la correlación basada en datos históricos de pares de divisas de múltiples archivos usando la biblioteca de pandas (para Python), y luego generar un diagrama de mapa de calor usando la biblioteca de Seaborn.

http://www.tradinggeeks.net/2015/08/calculating-correlation-in-python/


Si no tiene ganas de instalar scipy, he usado este hack rápido, ligeramente modificado de Programming Collective Intelligence :

(Editado para ser correcto)

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


Una alternativa puede ser una función scipy nativa de linregress que calcula:

pendiente: pendiente de la línea de regresión

intersección: intersección de la línea de regresión

valor r: coeficiente de correlación

valor p: valor p de dos lados para una prueba de hipótesis cuya hipótesis nula es que la pendiente es cero

stderr: Error estándar de la estimación

Y aquí hay un ejemplo:

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)

te devolverá:

LinregressResult(slope=0.20833333333333337, intercept=13.375, rvalue=0.14499815458068521, pvalue=0.68940144811669501, stderr=0.50261704627083648)


Usted puede hacer esto con pandas.DataFrame.corr , también:

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()

Esto da

0 1 2 0 1.000000 0.745601 0.916579 1 0.745601 1.000000 0.544248 2 0.916579 0.544248 1.000000


Puedes echar un vistazo a 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


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