Calcola il coefficiente di correlazione


9

Data una serie di numeri per gli eventi X e Y, calcolare il coefficiente di correlazione di Pearson. La probabilità di ciascun evento è uguale, quindi i valori previsti possono essere calcolati semplicemente sommando ogni serie e dividendo per il numero di prove.

Ingresso

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

Produzione

0.769

Il codice più corto vince. L'input può essere di stdin o arg. L'output avverrà tramite stdout.

Modifica: le funzioni incorporate non dovrebbero essere consentite (ad es. Valore atteso calcolato, varianza, deviazione, ecc.) Per consentire una maggiore diversità nelle soluzioni. Tuttavia, sentiti libero di dimostrare un linguaggio che ben si adatta al compito usando builtins (per la mostra).

Basato sull'idea di David per l'input per Mathematica (86 caratteri con media incorporata)

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

Battiscopa usando la nostra media (101 caratteri)

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

Molto bella razionalizzazione del codice Mathematica, usando il tuo mezzo!
DavidC,

Il codice MMa può essere abbreviato. Vedi il mio commento sotto la risposta di David. Inoltre, nel tuo codice puoi definirem=Total@#/Length@#&
Dr. belisarius,

Risposte:


3

PHP 144 byte

<?
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);

Prende l'input da STDIN, nel formato fornito nel post originale. Risultato:

,76909044055492

Utilizzo del prodotto dot vector:

dove sono i vettori di input regolati verso il basso di e rispettivamente.

Perl 112 byte

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

,76909044055492

Stessa alg, lingua diversa. In entrambi i casi sono state aggiunte nuove righe per "leggibilità" e non sono necessarie. L'unica notevole differenza di lunghezza è la prima riga: l'analisi dell'input.


5

Mathematica 34 byte

Ecco alcuni modi per ottenere la correlazione del momento del prodotto Pearson. Tutti producono lo stesso risultato. Dal dott. Belisarius: 34 byte

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

Funzione di correlazione integrata I : 15 caratteri

Ciò presuppone che xe ysiano elenchi corrispondenti a ciascuna variabile.

x~Correlation~y

0,76,909 mila


Funzione di correlazione integrata II : 31 caratteri

Ciò presuppone che d sia un elenco di coppie ordinate.

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

0,76,909 mila

L'uso di ;;per Allgrazie a A Simmons.


Basandosi sulla funzione di deviazione standard : 118 115 caratteri

La correlazione può essere determinata da:

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,76,909 mila


Correlazione arrotolata a mano : 119 caratteri

Supponendo xe ysono elenchi ...

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,76,909 mila


Ottengo 0,076909 per l'ultimo frammento di codice. Inoltre, perché hai s = StandardDeviation; quando s non viene mai applicato?
miglia

Considerando le ipotesi in risposta al Q-language, in Mathematica è solo x ~ Correlazione ~ y
Vitaliy Kaurov

@VitaliyKaurov, Sì, buon punto, ora preso in considerazione.
DavidC,

@milest. Ovviamente! StandardDeviation era "legacy" dalle soluzioni precedenti. Penso di riservo sper Sum.
DavidC,

@milest L'errore nell'output finale era anche dovuto al /(n-1)fatto di essere stato erroneamente riportato dalla soluzione precedente. Ora corretto.
DavidC,

2

Q

Supponendo che i builtin siano consentiti e i dati x, y siano vettori separati (7 caratteri):

x cor y

Se i dati sono memorizzati come coppie ordinate, come indicato da David Carraher, otteniamo (per 12 caratteri):

{(cor).(+)x}

I dati di correlazione non consistono normalmente in coppie ordinate?
DavidC,

Ho aggiunto un'alternativa per quel caso
skeevey del

2

MATLAB / Octave

Ai fini della dimostrazione solo dei built-in:

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

2

APL 57

Utilizzando l'approccio del prodotto dot:

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 byte

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

Questa volta in funzione di due argomenti. Utilizza la formula vettoriale per il calcolo.

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

Spiegazione

Prende due liste di e b come argomenti separati.

([:+/*%*&(+/)&.:*:)&(-+/%#)  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

Puoi fattorizzare xe ynella riga finale cucendoli insieme ,.per darti((m@:*/@|:-*/@m)%%:@*/@(m@:*:-*:@m))x,.y
Gareth,

Devo ammetterlo, il codice in sé sembra stupendo ... parlando come qualcuno che ama il suo codice non alfanumerico ...;)
WallyWest

Esiste una versione più corta di 24 byte +/ .*&(%+/&.:*:)&(-+/%#)riconosciuta da Oleg sui J forum .
miglia,

1

Python 3, 140 byte

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)

Sono definite 2 funzioni di supporto ( Ee S, rispettivamente, per il valore atteso e la deviazione standard). L'input è previsto come 2 iterabili (elenchi, tuple, ecc.). Provalo online .


1

Oracle SQL 11.2, 152 byte (per mostra)

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

Un-golfed

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 stringa di input deve utilizzare lo stesso separatore decimale del database.


1

Python 3 con SciPy, 52 byte (per mostra)

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

Una funzione anonima che riceve l'input dei due insiemi di dati come liste xe y, e restituisce il coefficiente di correlazione.

Come funziona

Non c'è molto da fare qui; SciPy ha un builtin che restituisce sia il coefficiente che il valore p per testare la non correlazione, quindi la funzione passa semplicemente i set di dati a questo e restituisce il primo elemento della (coefficient, p-value)tupla restituito dal builtin.

Provalo su Ideone

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.