计算相关系数


9

给定事件X和Y的一系列数字,请计算Pearson的相关系数。每个事件的概率相等,因此可以通过简单地将每个系列相加并除以试验次数来计算期望值。

输入项

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

输出量

0.769

最短的代码胜出。输入可以通过stdin或arg进行。输出将通过标准输出。

编辑:不应使用内置函数(即,计算的期望值,方差,偏差等),以允许解决方案具有更多多样性。但是,请使用内置程序(用于展示)随意演示一种非常适合该任务的语言。

基于David输入Mathematica的想法(使用内置均值的86个字符)

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

使用我们自己的平均值(101个字符)进行短裙

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

用您自己的意思很好地简化Mathematica代码!
DavidC 2012年

MMa代码可以缩短。请参阅我在David的回答下的评论。此外,您可以在代码中定义m=Total@#/Length@#&
belisarius博士2012年

Answers:


3

PHP 144字节

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

从STDIN接收输入,格式为原始文章中提供的格式。结果:

0.76909044055492

使用矢量点积:

其中是输入向量通过向下调整分别。

Perl 112字节

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

0.76909044055492

相同的算法,不同的语言。在这两种情况下,都添加了新行以提高“可读性”,而不是必需的。长度上唯一值得注意的区别是第一行:输入的解析。


5

Mathematica 34字节

这是获得皮尔逊乘积矩相关性的几种方法。它们都产生相同的结果。来自belisarius博士:34个字节

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

内置相关函数I:15个字符

假定xy是对应于每个变量的列表。

x~Correlation~y

0.76909


内置相关函数II:31个字符

假设d是有序对的列表。

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

0.76909

采用;;All多亏了西蒙斯。


依靠标准差功能118 115个字符

可以通过以下方式确定相关性:

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


手动相关性:119个字符

假设xy是清单...

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


我得到最后一个代码段的0.076909。还有为什么你有s = StandardDeviation; 何时从不应用s?
英里

考虑到答案Q-语言的假设,在数学这只是X〜相关〜Ÿ
维塔利Kaurov

@VitaliyKaurov,是的,很好,现在考虑在内。
DavidC 2012年

@milest。当然!StandardDeviation是早期解决方案中的“传统”。我想我会保留sSum
DavidC 2012年

@milest最终输出中的错误也是由于/(n-1)错误地从较早的解决方案中继承而来的。现在已更正。
DavidC 2012年

2

假设内置函数是允许的,并且x,y数据是单独的向量(7个字符):

x cor y

如果数据按有序对存储(如David Carraher所示),我们将得到(12个字符):

{(cor).(+)x}

相关数据通常不是由有序对组成吗?
DavidC 2012年

我为这种情况添加了其他选择
skeevey

2

MATLAB /八度

仅出于演示内置目的:

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

2

杀伤人员地雷57

使用点积方法:

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字节

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

这次作为一个带有两个参数的函数。使用向量公式进行计算。

用法

   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

说明

将两个列表ab作为单独的参数。

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

您可以将xy拼接在一起,,.从而排除and并在最后一行中给您((m@:*/@|:-*/@m)%%:@*/@(m@:*:-*:@m))x,.y
Gareth 2012年

我不得不承认,代码本身看起来很漂亮……以喜欢他的非字母数字代码的人的身份说话……;)
WallyWest '16

+/ .*&(%+/&.:*:)&(-+/%#)Oleg在J 论坛上认可了一个较短的24字节版本。
英里

1

Python 3,140个字节

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)

2辅助功能(E以及S,对于预期值和标准偏差,分别)被定义。预期输入为2个可迭代项(列表,元组等)。在线尝试


1

Oracle SQL 11.2,152个字节(用于展示)

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

未打高尔夫球

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
)

输入字符串应使用与数据库相同的十进制分隔符。


1

带有SciPy的Python 3,52个字节(用于展示)

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

一个匿名函数,将两个数据集的输入作为列表xy,并返回相关系数。

怎么运行的

这里没有很多事情发生。SciPy有一个内置函数,它同时返回系数和p值以测试非相关性,因此该函数仅将数据集传递给该函数,并返回(coefficient, p-value)内置函数返回的元组的第一个元素。

在Ideone上尝试

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.