Calcular el coeficiente de correlación.


9

Dada una serie de números para los eventos X e Y, calcule el coeficiente de correlación de Pearson. La probabilidad de cada evento es igual, por lo que los valores esperados se pueden calcular simplemente sumando cada serie y dividiendo por el número de ensayos.

Entrada

1   6.86
2   5.92
3   6.08
4   8.34
5   8.7
6   8.16
7   8.22
8   7.68
9   12.04
10  8.6
11  10.96

Salida

0.769

El código más corto gana. La entrada puede ser por stdin o arg. La salida será por stdout.

Editar: No se deben permitir las funciones integradas (es decir, el valor esperado calculado, la varianza, la desviación, etc.) para permitir una mayor diversidad en las soluciones. Sin embargo, siéntase libre de demostrar un lenguaje que sea adecuado para la tarea usando builtins (para exhibición).

Basado en la idea de David de entrada para Mathematica (86 caracteres usando la media incorporada)

m=Mean;x=d[[All,1]];y=d[[All,2]];(m@(x*y)-m@x*m@y)/Sqrt[(m@(x^2)-m@x^2)(m@(y^2)-m@y^2)]

m = Mean;
x = d[[All,1]];
y = d[[All,2]];
(m@(x*y) - m@x*m@y)/((m@(x^2) - m@x^2)(m@(y^2) - m@y^2))^.5

Bordeando usando nuestra propia media (101 caracteres)

m=Total[#]/Length[#]&;x=d[[All,1]];y=d[[All,2]];(m@(x*y)-m@x*m@y)/((m@(x^2)-m@x^2)(m@(y^2)-m@y^2))^.5

m = Total[#]/Length[#]&;
x = d[[All,1]];
y = d[[All,2]];
(m@(x*y)-m@x*m@y)/((m@(x^2)-m@x^2)(m@(y^2)-m@y^2))^.5

¡Muy buena racionalización del código de Mathematica, usando su propio medio!
DavidC

El código MMa se puede acortar. Vea mi comentario bajo la respuesta de David. Además, en su código puede definirm=Total@#/Length@#&
Dr. belisarius

Respuestas:


3

PHP 144 bytes

<?
for(;fscanf(STDIN,'%f%f',$$n,${-$n});$f+=${-$n++})$e+=$$n;
for(;$$i;$z+=$$i*$a=${-$i++}-=$f/$n,$y+=$a*$a)$x+=$$i*$$i-=$e/$n;
echo$z/sqrt($x*$y);

Toma la entrada de STDIN, en el formato proporcionado en la publicación original. Resultado:

0.76909044055492

Usando el producto punto vectorial:

donde están los vectores de entrada ajustados hacia abajo por y respectivamente.

Perl 112 bytes

/ /,$e+=$`,$f+=$',@v=($',@v)for@u=<>;
$x+=($_-=$e/$.)*$_,$y+=($;=$f/$.-pop@v)*$;,$z-=$_*$;for@u;
print$z/sqrt$x*$y

0.76909044055492

Mismo alg, diferente idioma. En ambos casos, se han agregado nuevas líneas para 'legibilidad', y no son necesarias. La única diferencia notable en la longitud es la primera línea: el análisis de la entrada.


5

Mathematica 34 bytes

Aquí hay algunas maneras de obtener la correlación de momento del producto Pearson. Todos producen el mismo resultado. Del Dr. belisario: 34 bytes

Dot@@Normalize/@(#-Mean@#&)/@{x,y}

Función de correlación incorporada I : 15 caracteres

Esto supone que xy yson listas correspondientes a cada variable.

x~Correlation~y

0,76909


Función de correlación incorporada II : 31 caracteres

Esto supone que d es una lista de pares ordenados.

d[[;;,1]]~Correlation~d[[;;,2]]

0,76909

El uso de ;;por Allgracias a A Simmons.


Confiando en la función de desviación estándar : 118 115 caracteres

La correlación puede determinarse por:

s=StandardDeviation;
m=Mean;
n=Length@d;
x=d[[;;,1]];
y=d[[;;,2]];
Sum[((x[[i]]-m@x)/s@x)((y[[i]]-m@y)/s@y),{i,n}]/(n-1)

0,76909


Correlación enrollada a mano : 119 caracteres

Asumiendo xy yson listas ...

s=Sum;n=Length@d;m@p_:=Tr@p/n;
(s[(x[[i]]-m@x)(y[[i]]-m@y),{i,n}]/Sqrt@(s[(x[[i]]-m@x)^2,{i,n}] s[(y[[i]] - m@y)^2,{i,n}]))

0,76909


Obtengo 0.076909 para el último fragmento de código. Además, ¿por qué tienes s = StandardDeviation; cuando s nunca se aplica?
millas

Considerando los supuestos en respuesta para el lenguaje Q, en Mathematica es solo x ~ Correlación ~ y
Vitaliy Kaurov

@VitaliyKaurov, sí, buen punto, ahora tomado en cuenta.
DavidC

@milest. ¡Por supuesto! StandardDeviation fue "legado" de las soluciones anteriores. Creo que voy a reservar spara Sum.
DavidC

@milest El error en el resultado final también se debió a /(n-1)que la solución anterior lo transfirió por error . Ahora corregido.
DavidC

2

Q

Suponiendo que los valores incorporados están permitidos y los datos x, y son vectores separados (7 caracteres):

x cor y

Si los datos se almacenan como pares ordenados, como lo indica David Carraher, obtenemos (para 12 caracteres):

{(cor).(+)x}

¿Los datos de correlación normalmente no consisten en pares ordenados?
DavidC


2

MATLAB / Octave

Con el fin de demostrar únicamente los elementos integrados:

octave:1> corr(X,Y)
ans =  0.76909
octave:2> 

2

APL 57

Usando el enfoque del producto punto:

a←1 2 3 4 5 6 7 8 9 10 11

b←6.86 5.92 6.08 8.34 8.7 8.16 8.22 7.68 12.04 8.6 10.96

(a+.×b)÷((+/(a←a-(+/a)÷⍴a)*2)*.5)×(+/(b←b-(+/b)÷⍴b)*2)*.5

0.7690904406         

2

J, 30 27 bytes

([:+/*%*&(+/)&.:*:)&(-+/%#)

Esta vez como una función tomando dos argumentos. Utiliza la fórmula vectorial para calcularlo.

Uso

   f =: ([:+/*%*&(+/)&.:*:)&(-+/%#)
   (1 2 3 4 5 6 7 8 9 10 11) f (6.86 5.92 6.08 8.34 8.7 8.16 8.22 7.68 12.04 8.6 10.96)
0.76909

Explicación

Toma dos listas una y b como argumentos separados.

([:+/*%*&(+/)&.:*:)&(-+/%#)  Input: a on LHS, b on RHS
                   &(     )  For a and b
                         #     Get the count
                      +/       Reduce using addition to get the sum
                        %      Divide the sum by the count to get the average
                     -         Subtract the initial value from the average
                             Now a and b have both been shifted by their average
                             For both a and b
                *:             Square each value
         (+/)&.:               Reduce the values using addition to get the sum
                               Apply in the inverse of squaring to take the square root
                               of the sum to get the norm
       *&                    Multiply norm(a) by norm(b)
     *                       Multiply a and b elementwise
      %                      Divide a*b by norm(a)*norm(b) elementwise
 [:+/                        Reduce using addition to the sum which is the
                             correlation coefficient and return it

Puede factorizar el xy yen la línea final uniéndolos ,.para darle((m@:*/@|:-*/@m)%%:@*/@(m@:*:-*:@m))x,.y
Gareth

Tengo que admitir que el código en sí mismo se ve hermoso ... hablando como alguien que ama su código no alfanumérico ...;)
WallyWest

Hay una versión más corta de 24 bytes +/ .*&(%+/&.:*:)&(-+/%#)reconocido por Oleg sobre los J foros .
millas

1

Python 3, 140 bytes

E=lambda x:sum(x)/len(x)
S=lambda x:(sum((E(x)-X)**2for X in x)/len(x))**.5
lambda x,y:E([(X-E(x))*(Y-E(y))for X,Y in zip(x,y)])/S(x)/S(y)

Se definen 2 funciones auxiliares ( Ey S, para el valor esperado y la desviación estándar, respectivamente). La entrada se espera como 2 iterables (listas, tuplas, etc.). Pruébalo en línea .


1

Oracle SQL 11.2, 152 bytes (para exhibición)

SELECT CORR(a,b)FROM(SELECT REGEXP_SUBSTR(:1,'[^ ]+',1,2*LEVEL-1)a,REGEXP_SUBSTR(:1,'[^ ]+',1,2*LEVEL)b FROM DUAL CONNECT BY INSTR(:1,' ',2,LEVEL-1)>0);

Sin golf

SELECT CORR(a,b)
FROM
(
  SELECT REGEXP_SUBSTR(:1, '[^ ]+', 1, 2*LEVEL-1)a, REGEXP_SUBSTR(:1, '[^ ]+', 1, 2*LEVEL)b
  FROM DUAL
  CONNECT BY INSTR(:1, ' ', 2, LEVEL - 1) > 0
)

La cadena de entrada debe usar el mismo separador decimal que la base de datos.


1

Python 3 con SciPy, 52 bytes (para exhibición)

from scipy.stats import*
lambda x,y:pearsonr(x,y)[0]

Una función anónima que toma la entrada de los dos conjuntos de datos como listas xy y, y devuelve el coeficiente de correlación.

Cómo funciona

No hay mucho que hacer aquí; SciPy tiene un valor incorporado que devuelve tanto el coeficiente como el valor p para probar la no correlación, por lo que la función simplemente pasa los conjuntos de datos a esto y devuelve el primer elemento de la (coefficient, p-value)tupla devuelto por el valor incorporado.

Pruébalo en Ideone

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.