Рассчитать коэффициент корреляции


9

Учитывая последовательность чисел для событий X и Y, рассчитайте коэффициент корреляции Пирсона. Вероятность каждого события равна, поэтому ожидаемые значения могут быть рассчитаны путем простого суммирования каждой серии и деления на количество испытаний.

вход

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

Самый короткий код выигрывает. Ввод может быть через стандартный ввод или аргумент. Выход будет через стандартный вывод.

Редактировать: встроенные функции не должны быть разрешены (т.е. рассчитаны ожидаемые значения, отклонения, отклонения и т. Д.), Чтобы обеспечить большее разнообразие решений. Тем не менее, не стесняйтесь демонстрировать язык, который хорошо подходит для этой задачи, используя встроенные функции (для выставки).

Основано на идее Дэвида для ввода в 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

Код MMa может быть сокращен. Смотрите мой комментарий под ответом Дэвида. Кроме того, в вашем коде вы можете определитьm=Total@#/Length@#&
Dr. belisarius 12.12.12

Ответы:


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 байта

Вот несколько способов получить корреляцию моментов произведения Пирсона. Все они дают одинаковый результат. От доктора Велизария: 34 байта

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

Встроенная корреляционная функция I : 15 символов

Это предполагает, что xи yявляются списки, соответствующие каждой переменной.

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 символов

Принимая xи yсписки ...

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-язык, в Mathematica это просто x ~ Корреляция ~ y
Виталий Кауров

@VitaliyKaurov, да, подмечено, теперь учтено.
DavidC

@milest. Конечно! Стандартное отклонение было «наследием» от более ранних решений. Думаю, я зарезервирую sдля Sum.
DavidC

@milest Ошибка в окончательном выводе также была вызвана /(n-1)ошибочным переносом из более раннего решения. Сейчас исправлено.
DavidC

2

Q

Предполагая, что встроенные функции разрешены, а данные x, y являются отдельными векторами (7 символов):

x cor y

Если данные хранятся в виде упорядоченных пар, как указано Дэвидом Каррахером, мы получаем (для 12 символов):

{(cor).(+)x}

Разве корреляционные данные обычно не состоят из упорядоченных пар?
DavidC

Я добавил альтернативу для этого случая
2012 года

2

MATLAB / Octave

Только для демонстрации встроенных модулей:

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

2

APL 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

объяснение

Принимает два списка a и b как отдельные аргументы.

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

Вы можете вычленить xи yв последней строке, соединив их вместе с, ,.чтобы дать вам((m@:*/@|:-*/@m)%%:@*/@(m@:*:-*:@m))x,.y
Гарет

Я должен признать, что код сам по себе выглядит великолепно ... говоря как тот, кто любит его не буквенно-цифровой код ...;)
WallyWest

На +/ .*&(%+/&.:*:)&(-+/%#)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для ожидаемого значения и стандартного отклонения соответственно). Ввод ожидается в виде двух итераций (списки, кортежи и т. Д.). Попробуйте онлайн .


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

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
)

Входная строка должна использовать тот же десятичный разделитель, что и база данных.


1

Python 3 с SciPy, 52 байта (для выставки)

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

Анонимная функция , которая принимает данные из двух наборов данных в виде списков xи y, и возвращает коэффициент корреляции.

Как это работает

Здесь не так много происходит; SciPy имеет встроенную функцию, которая возвращает коэффициент и значение p для тестирования некорреляции, поэтому функция просто передает в нее наборы данных и возвращает первый элемент (coefficient, p-value)кортежа, возвращенный встроенной функцией.

Попробуйте это на Ideone

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.