Кто это распределение вероятностей?


16

Вступление

В этом задании вам предоставляется список неотрицательных чисел с плавающей запятой, составленных независимо от некоторого распределения вероятностей. Ваша задача - вывести это распределение из чисел. Чтобы задача выполнилась, у вас есть только пять дистрибутивов на выбор.

Обратите внимание, что все вышеприведенные распределения имеют среднее значение ровно 1/2.

Задание

Ваш ввод представляет собой массив неотрицательных чисел с плавающей запятой длиной от 75 до 100 включительно. Ваш вывод должен состоять из одной буквы UTBEG, в зависимости от того, из каких вышеупомянутых дистрибутивов вы предполагаете цифры.

Правила и оценки

Вы можете дать либо полную программу, либо функцию. Стандартные лазейки запрещены.

В этом хранилище есть пять текстовых файлов, по одному для каждого дистрибутива, каждый ровно по 100 строк. Каждая строка содержит разделенный запятыми список от 75 до 100 чисел с плавающей запятой, взятых независимо от распределения и усеченных до 7 цифр после десятичной точки. Вы можете изменить разделители в соответствии с форматом массива вашего языка. Чтобы квалифицироваться как ответ, ваша программа должна правильно классифицировать не менее 50 списков из каждого файла . Оценка правильного ответа - количество байтов + общее количество ошибочно классифицированных списков . Самый низкий балл побеждает.


Я, наверное, должен был спросить раньше, но сколько ожидается оптимизация в отношении тестовых случаев? Я нахожусь в точке, где я могу улучшить свой результат, настроив несколько параметров, но влияние на результат, вероятно, будет зависеть от данных тестовых случаев.
Деннис

2
@Dennis Вы можете оптимизировать столько, сколько хотите, контрольные примеры являются фиксированной частью задачи.
Згарб

Ю НЕТ Студент-т раздача? = (
N3buchadnezzar

Ответы:


6

Юлия, 60 62 байта + 25 2 ошибки = 82 64

k->"EGTBU"[(V=std(k);any(k.>1)?V>.34?1:2:V<.236?3:V>.315?4:5)]

Это довольно просто. Дисперсия для распределений в основном различна - 1/4 для экспоненциального, 1/8 для бета, 1/12 для гаммы и униформы и 1/24 для треугольного. Таким образом, если мы используем дисперсию (здесь используется stdстандартное отклонение, квадратный корень дисперсии) для определения вероятного распределения, нам нужно только сделать больше, чтобы отличить гамму от равномерной; для этого мы ищем значение больше 1 (используя any(k.>1)) - при этом мы проверяем как экспоненциальную, так и гамму, поскольку это улучшает общую производительность.

Чтобы сохранить байт, индексация строки "EGTBU"выполняется вместо прямой оценки строки в условных выражениях.

Для тестирования сохраните txt-файлы в каталог (сохраняя имена как есть) и запустите Julia REPL в этом каталоге. Затем прикрепите функцию к имени как

f=k->"EGTBU"[(V=std(k);any(k.>1)?V>.34?1:2:V<.236?3:V>.315?4:5)]

и используйте следующий код для автоматизации тестирования (он будет считывать из файла, преобразовывать в массив массивов, использовать функцию и выводить для каждого несоответствия):

m=0;for S=["B","E","G","T","U"] K=open(S*".txt");F=readcsv(K);
M=Array{Float64,1}[];for i=1:100 push!(M,filter(j->j!="",F[i,:]))end;
close(K);n=0;
for i=1:100 f(M[i])!=S[1]&&(n+=1;println(i," "S,"->",f(M[i])," ",std(M[i])))end;
println(n);m+=n;end;println(m)

Вывод будет состоять из строк, содержащих несовпадающий регистр, правильное распределение -> определенное распределение и вычисленную дисперсию (например, 13 G->E 0.35008999281668357 означает, что 13-я строка в G.txt, которая должна быть гамма-распределением, определена как экспоненциальная). распределение со стандартным отклонением 0.35008999 ...)

После каждого файла он также выводит количество несоответствий для этого файла, а затем в конце также отображает общее количество несоответствий (и при запуске, как указано выше, должно отображаться значение 2). Между прочим, он должен иметь 1 несоответствие для G.txt и 1 несоответствие для U.txt


7

R, 202 192 184 182 162 154 байта + 0 ошибок

function(x)c("U","T","B","E","G")[which.max(lapply(list(dunif(x),sapply(x,function(y)max(0,2-4*abs(.5-y))),dbeta(x,.5,.5),dexp(x,2),dgamma(x,3,6)),prod))]

Это основано на байесовской формуле P (D = d | X = x) = P (X = x | D = d) * P (D = d) / P (X = x), где D - распределение, а X случайная выборка Выберем d так, чтобы P (D = d | X = x) было наибольшим из 5.

Я предполагаю, что плоский априор (т.е. P (D = di) = 1/5 для i в [1,5]), что означает, что P (D = d) в числителе одинаков во всех случаях (и знаменатель будет в любом случае одинаковы во всех случаях), поэтому мы можем убрать все, кроме P (x = X | D = d), которое (кроме треугольного распределения) упрощается до нативных функций в R.

ungolfed:

function(x){
  u=prod(dunif(x))
  r=prod(sapply(x,function(y)max(0,2-4*abs(.5-y))))
  b=prod(dbeta(x,.5,.5))
  e=prod(dexp(x,2))
  g=prod(dgamma(x,3,6))
  den=.2*u+.2*r+.2*b+.2*e+.2*g
  c("U","T","B","E","G")[which.max(c(u*.2/den,r*.2/den,b*.2/den,e*.2/den,g*.2/den))]
}

Обратите внимание, что версия без гольфа не совсем эквивалентна версии в гольфе, потому что избавление от знаменателя позволяет избежать случая Inf / Inf, который возникает, если вы разрешаете бета-распределению находиться на закрытом интервале [0,1] вместо (0, 1) - как пример данных. Дополнительный оператор if справился бы с этим, но, поскольку он предназначен только для иллюстративных целей, вероятно, не стоит добавлять сложность, которая не лежит в основе алгоритма.

Спасибо @Alex A. за дополнительные сокращения кода. Специально для чего .max!


1
Вы можете получить это до 190 байт, удалив разрыв строки после открытия {и один перед закрытием }, а также наложение псевдонимов prod, например P=prod, выполнение P(dunif(x))и т. Д. Функция не нуждается в имени, чтобы быть действительной отправкой, поэтому вы можете удалить p=, Также отличная работа. :)
Алекс А.

2
Вы можете получить его до 182, используя приведенные выше предложения и используя which.max(c(u,r,b,e,g))вместо c(u,r,b,e,g)==max(c(u,r,b,e,g)).
Алекс А.

156:function(x){c("U","T","B","E","G")[which.max(lapply(list(dunif(x),sapply(x,function(y)max(0,2-4*abs(.5-y))),dbeta(x,.5,.5),dexp(x,2),dgamma(x,3,6)),prod))]}
Алекс А.

Как ты смеешь использовать R для задачи, связанной со статистикой!
Flawr

6

CJam, 76

{2f*__{(z.4<},,%,4e<"UBT"="EG"\*\$-2=i3e<=}

Исходный код имеет длину 43 байта и неправильно классифицирует 33 списка.

верификация

$ count()(sort | uniq -c | sort -nr)
$ cat score.cjam
qN%{',' er[~]
  {2f*__{(z.4<},,%,4e<"UBT"="EG"\*\$-2=i3e<=}
~N}/
$ for list in U T B E G; { echo $list; cjam score.cjam < $list.txt | count; }
U
     92 U
      6 B
      2 T
T
    100 T
B
     93 B
      7 U
E
     92 E
      8 G
G
     90 G
      6 E
      3 T
      1 U

идея

Отличить экспоненциальное и гамма-распределение от остальных очень легко, поскольку они являются единственными, которые принимают значения больше 1 .

Чтобы выбрать гамму , экспоненту и другие, мы посмотрим на второе по величине значение выборки.

  • Если оно лежит в [1.5, ∞) , мы предполагаем гамму .

  • Если оно лежит в [1, 1.5) , мы предполагаем экспоненциальный .

  • Если оно лежит в [0, 1) , у нас есть три оставшиеся возможности.

    Остальные распределения могут быть дифференцированы по проценту значений выборки, которые лежат близко к среднему значению ( 0,5 ).

    Мы делим длину выборки на количество значений, попадающих в (0,3, 0,7), и посмотрим на полученный коэффициент.

    • Если оно лежит в (1, 2] , мы предполагаем треугольное .

    • Если оно лежит в (2, 3] , мы предполагаем равномерное .

    • Если оно лежит в (3, ∞) , мы предполагаем бета .

Код

2f*    e# Multiply all sample values by 2.
__     e# Push to copies of the sample.
{      e# Filter; for each (doubled) value in the sample:
  (z   e#   Subtract 1 and apply absolute value.
  .4<  e#   Check if the result is smaller than 0.4.
},     e# If it is, keep the value.
,/     e# Count the kept values (K).
%      e# Select every Kth value form the sample, starting with the first.
,      e# Compute the length of the resulting array.
       e# This performs ceiled division of the sample length by K.
4e<    e# Truncate the quotient at 4.
"UBT"= e# Select 'T' for 2, 'U' for 3 and 'B' for 4.
"EG"\* e# Place the selected character between 'E' and 'G'.
\$     e# Sort the remaining sample.
-2=i   e# Extract the second-highest (doubled) value and cast to integer.
3e<    e# Truncate the result at 3.
=      e# Select 'E' for 3, 'G' for 2 and the character from before for 1.

3

Матлаб, 428 328 байтов + 33 неправильно классифицированы

Эта программа в основном сравнивает реальный CDF с оценочным с учетом данных, а затем вычисляет среднее расстояние между этими двумя: я думаю, что изображение объясняет больше:

введите описание изображения здесь

Данные, показанные на этом рисунке, довольно ясно показывают, что он относится к бирюзовому дистрибутиву, так как он довольно близок к этому, так что это в основном то, что делает моя программа. Это, вероятно, может быть несколько больше в гольфе. Для меня это был прежде всего концептуальный вызов, а не игра в гольф.

Этот подход также не зависит от выбранных PDF-файлов, он будет работать для любого набора дистрибутивов.

Следующий (ungolfed) код должен показать, как это делается. Версия для гольфа ниже.

function r=p(x);
data=sort(x(1:75));
%% cumulative probability distributiosn
fu=@(x)(0<x&x<1).*x+(1<=x).*1;
ft=@(x)(0<x&x< 0.5).* 2.*x.^2+(1-2*(1-x).^2).*(0.5<=x&x<1)+(1<=x);
fb=@(x)(0<x&x<1).*2.*asin(sqrt(x))/pi+(1<=x);
fe=@(x)(0<x).*(1-exp(-2*x));
fg=@(x)(0<x).*(1-exp(-x*6).*(1+x*6+1/2*(6*x).^2));
fdata = @(x)sum(bsxfun(@le,data,x.'),2).'/length(data);
f = {fe,fg,fu,ft,fb};
str='EGUTB';
%calculate distance to the different cdfs at each datapoint
for k=1:numel(f);
dist(k) = max(abs(f{k}(x)-fdata(x)));
end;
[~,i]=min(dist);
r=str(i);
end

Полностью гольф-версия:

function r=p(x);f={@(x)(0<x).*(1-exp(-2*x)),@(x)(0<x).*(1-exp(-x*6).*(1+x*6+18*x.^2)),@(x)(0<x&x<1).*x+(1<=x),@(x)(0<x&x<.5).*2.*x.^2+(1-2*(1-x).^2).*(.5<=x&x<1)+(1<=x),@(x)(0<x&x<1).*2.*asin(sqrt(x))/pi+(1<=x)};s='EGUTB';for k=1:5;d(k)=max(abs(f{k}(x)-sum(bsxfun(@le,x,x.'),2).'/nnz(x)));end;[~,i]=min(d(1:5-3*any(x>1)));r=s(i)

2

Perl, 119 байт + 8 неправильных классификаций = 127

Я принял крошечное дерево решений по трем функциям:

  • $ o: boolean: если есть образцы> 1.0
  • $ t: count: 0-й минус 6-й 13-й отрезанный в диапазоне 0-1,
  • $ h: count: 0-й минус 6-й плюс 12-й 13-й отрезанный в диапазоне 0-1

Вызывается с perl -F, -lane -e '...'. Я не уверен, стоит ли добавлять штраф за нестандартные параметры. Если бы запятые были пробелами, я думаю, я мог бы обойтись без -F,

для (@F) {$ б [$ _ * 13] ++; $ O ++, если $ _> 1}
$ H = ($ T = $ B [0] - $ Ь [6]) + $ Ь [12];
печать $ O ($ т> -2 "е": "г"?): ($ ч = 19 "Ъ": "U")?);
$ А = @ Ь = ()

Слегка отформатированный вывод (без флага -l):

bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
    bbbbbbbbbbbbbbbbbbbbbbbbubbbbbbbbbbbbbbbbbbbbbbb
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
    eeegeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
gggggggegggggggggggggggggggggggggggggggggggggggggggg
    gggggggggggggggggggggggggggggggggggggggggggggggg
tttttttttttttttttttttttttttttttttttttttttttttttttttt
    ttttttttttttttttttttttttttttuttttttttttttutttttt
uuuuuuuuuuuuuuuuuuuuuuuuuuutuuuuuuuuuuuuuuuubuuuuuuu
    uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuutuuuu

0

Python, 318 байт + 35 ошибочных классификаций

from scipy.stats import*
from numpy import*
def f(l):
    r={'U':kstest(l,'uniform')[1],'T':kstest(l,'triang',args=(.5,))[1],'B':kstest(l,'beta',args=(.5,.5))[1],'E':kstest(l,'expon',args=(0,.5,))[1],'G':kstest(l,'gamma',args=(3,0,1/6.0))[1]}
    if sum([x>1 for x in l]): r['U'],r['T'],r['B']=0,0,0
    return max(r,key=r.get)

Идея: распределение угадывается по p-значению критерия Колмогорова-Смирнова.

Тестовое задание

from scipy.stats import*
from numpy import*
import os
from io import StringIO
dir=os.path.dirname(os.path.abspath(__file__))+"/random-data-master/"

def f(l):
    r={'U':kstest(l,'uniform')[1],'T':kstest(l,'triang',args=(.5,))[1],'B':kstest(l,'beta',args=(.5,.5))[1],'E':kstest(l,'expon',args=(0,.5,))[1],'G':kstest(l,'gamma',args=(3,0,1/6.0))[1]}
    if sum([x>1 for x in l]): r['U'],r['T'],r['B']=0,0,0
    return max(r,key=r.get)

U=[line.rstrip('\n').split(',') for line in open(dir+'U.txt')]
U=[[float(x) for x in r] for r in U]
T=[line.rstrip('\n').split(',') for line in open(dir+'T.txt')]
T=[[float(x) for x in r] for r in T]
B=[line.rstrip('\n').split(',') for line in open(dir+'B.txt')]
B=[[float(x) for x in r] for r in B]
E=[line.rstrip('\n').split(',') for line in open(dir+'E.txt')]
E=[[float(x) for x in r] for r in E]
G=[line.rstrip('\n').split(',') for line in open(dir+'G.txt')]
G=[[float(x) for x in r] for r in G]

i,_u,_t,_b,_e,_g=0,0,0,0,0,0
for u,t,b,e,g in zip(U,T,B,E,G):
    _u+=1 if f(u)=='U' else 0
    _t+=1 if f(t)=='T' else 0
    _b+=1 if f(b)=='B' else 0
    _e+=1 if f(e)=='E' else 0
    _g+=1 if f(g)=='G' else 0
    print f(u),f(t),f(b),f(e),f(g)
print _u,_t,_b,_e,_g,100*5-_u-_t-_b-_e-_g
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.