Хто такий розподіл ймовірностей?


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), які (крім трикутного розподілу) спрощують до власних функцій у Р.

неозорений:

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) - як це роблять вибіркові дані. Додатковий, якщо твердження вирішує це, але, оскільки це лише для ілюстративних цілей, мабуть, не варто додавати складності, яка не лежить в основі алгоритму.

Дякуємо @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

Matlab, 428 328 байт + 33 неправильно класифікованих

Ця програма, по суті, порівнює справжній CDF з оцінкою, отриманою за даними, а потім обчислює середню відстань між цими двома: я думаю, що зображення пояснює більше:

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

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

Цей підхід також не залежить від обраного файлу pdfs, він би працював для будь-якого набору дистрибутивів.

Наступний (neololfed) код повинен показувати, як це робиться. Версія для гольфу знаходиться нижче.

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: підрахунок: 0-й мінус 6-й 13-ій обріз у діапазоні 0-1,
  • $ h: підрахунок: 0-й мінус 6-й плюс 12-й 13-ій обріз у діапазоні 0-1

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

для (@F) {$ b [$ _ * 13] ++; $ o ++, якщо $ _> 1}
$ h = ($ t = $ b [0] - $ b [6]) + $ b [12];
друкувати $ o? ($ t> -2? "e": "g"): ($ h = 19? "b": "u"));
$ o = @ b = ()

Злегка відформатований вихід (без прапора -l):

bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
    bbbbbbbbbbbbbbbbbbbbbbbubbbbbbbbbbbbbbbbbbbbbbb
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
    eeegeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
gggggggegggggggggggggggggggggggggggggggggggggggggggg
    gggggggggggggggggggggggggggggggggggggggggggggggg
tttttttttttttttttttttttttttttttttttttttttttttttttttt
    ttttttttttttttttttttttttttttuttttttttttttuttttttt
ууууууууууууууууууууууутуууууууууууууууууууууууууууууууууууууууууууу
    uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

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.