Obliczyć współczynnik korelacji

9

Biorąc pod uwagę serię liczb dla zdarzeń X i Y, oblicz współczynnik korelacji Pearsona. Prawdopodobieństwo każdego zdarzenia jest równe, więc oczekiwane wartości można obliczyć, po prostu sumując każdą serię i dzieląc przez liczbę prób.

Wejście

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

Wynik

0.769

Najkrótszy kod wygrywa. Dane wejściowe mogą być stdin lub arg. Wyjście będzie według standardowego wyjścia.

Edycja: Wbudowane funkcje nie powinny być dozwolone (tj. Obliczona oczekiwana wartość, wariancja, odchylenie itp.), Aby umożliwić większą różnorodność rozwiązań. Zapraszam jednak do zademonstrowania języka, który jest dobrze dopasowany do zadania, za pomocą wbudowanych funkcji (na wystawę).

Na podstawie pomysłu Davida dotyczącego danych wejściowych dla Mathematica (86 znaków przy użyciu wbudowanej średniej)

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

Cokół za pomocą naszego własnego środka (101 znaków)

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
mile
źródło
Bardzo fajne usprawnienie kodu Mathematica, używając własnego środka!
DavidC
Kod MMa można skrócić. Zobacz mój komentarz pod odpowiedzią Davida. Ponadto w kodzie możesz zdefiniowaćm=Total@#/Length@#&
dr belisarius,

Odpowiedzi:

3

PHP 144 bajty

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

Pobiera dane wejściowe ze STDIN, w formacie podanym w oryginalnym poście. Wynik:

0,76909044055492

Za pomocą iloczynu wektorowego:

gdzie wektory wejściowe są korygowane w dół odpowiednio przez i .

Perl 112 bajtów

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

0,76909044055492

Ten sam alg, inny język. W obu przypadkach dodano nowe wiersze dla „czytelności” i nie są one wymagane. Jedyną zauważalną różnicą długości jest pierwszy wiersz: parsowanie danych wejściowych.

primo
źródło
5

Matematyka 34 bajty

Oto kilka sposobów uzyskania korelacji momentu produktu Pearson. Wszystkie dają ten sam wynik. Od dr Belizariusza: 34 bajty

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

Wbudowana funkcja korelacji I : 15 znaków

Zakłada się, że xi yto listy odpowiadające każdej zmiennej.

x~Correlation~y

0,76909


Wbudowana funkcja korelacji II : 31 znaków

Zakłada się, że d jest listą uporządkowanych par.

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

0,76909

Zastosowanie ;;dla AllDzięki Simmons.


Poleganie na funkcji odchylenia standardowego : 118 115 znaków

Korelacja może być określona przez:

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


Ręcznie walcowana korelacja : 119 znaków

Zakładając xi ysą to listy ...

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

DavidC
źródło
Dostaję 0,076909 za ostatni fragment kodu. Również dlaczego masz s = StandardDeviation; kiedy s nigdy nie jest stosowane?
mile
Biorąc pod uwagę założenia w odpowiedzi na język Q, w Mathematica jest to tylko x ~ Korelacja ~ y
Vitaliy Kaurov,
@VitaliyKaurov, Tak, dobra uwaga, teraz brana pod uwagę.
DavidC
@milest. Oczywiście! StandardDeviation był „dziedzictwem” wcześniejszych rozwiązań. Zastrzegamy, że będę sza Sum.
DavidC
@milest Błąd w końcowym wyjściu był również spowodowany /(n-1)błędnym przeniesieniem z wcześniejszego rozwiązania. Teraz poprawione.
DavidC
2

Q

Zakładając, że wbudowane są dozwolone, a dane x, y są oddzielnymi wektorami (7 znaków):

x cor y

Jeśli dane są przechowywane jako uporządkowane pary, jak wskazał David Carraher, otrzymujemy (dla 12 znaków):

{(cor).(+)x}
skeevey
źródło
Czy dane korelacji zwykle nie zawierają uporządkowanych par?
DavidC
Dodałem al alternatywę dla tej sprawy
skeevey
2

MATLAB / Octave

W celu pokazania tylko wbudowanych elementów:

octave:1> corr(X,Y)
ans =  0.76909
octave:2> 
Paul R.
źródło
2

APL 57

Przy użyciu metody iloczynu:

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         
Graham
źródło
2

J, 30 27 bajtów

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

Tym razem jako funkcja przyjmująca dwa argumenty. Do obliczenia używa wzoru wektorowego.

Stosowanie

   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

Wyjaśnienie

Zajmuje dwie listy A i B jako osobne argumenty.

([:+/*%*&(+/)&.:*:)&(-+/%#)  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
mile
źródło
Możesz wyliczyć xi yw ostatniej linii, łącząc je razem, ,.aby dać ci((m@:*/@|:-*/@m)%%:@*/@(m@:*:-*:@m))x,.y
Gareth
Muszę przyznać, że sam kod wygląda wspaniale ... mówiąc jak ktoś, kto kocha swój niealfanumeryczny kod ...;)
WallyWest
Na forach+/ .*&(%+/&.:*:)&(-+/%#) J Oleg rozpoznaje krótszą 24-bajtową wersję .
mile
1

Python 3, 140 bajtów

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)

Funkcje pomocnicze 2 ( Ei S, na oczekiwanej wartości i odchylenia standardowego, odpowiednio), są zdefiniowane. Dane wejściowe są oczekiwane jako 2 iterowalne (listy, krotki itp.). Wypróbuj online .

Mego
źródło
1

Oracle SQL 11.2, 152 bajty (na wystawę)

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

Nie grał w golfa

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
)

Łańcuch wejściowy powinien używać tego samego separatora dziesiętnego co baza danych.

Jeto
źródło
1

Python 3 z SciPy, 52 bajty (na wystawę)

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

Anonimowa funkcja, która pobiera dane wejściowe dwóch zestawów danych jako listy x i y, i zwraca współczynnik korelacji.

Jak to działa

Tutaj niewiele się dzieje; SciPy ma wbudowaną funkcję, która zwraca zarówno współczynnik, jak i wartość p dla testowania braku korelacji, więc funkcja po prostu przekazuje do tego zestawy danych i zwraca pierwszy element(coefficient, p-value) krotki zwrócony przez wbudowaną funkcję.

Wypróbuj na Ideone

TheBikingViking
źródło