그 확률 분포는 누구입니까? 1/2을 의미합니다. 작업 입력은 음수가 아닌 부동 소수점

소개

이 도전에서는 일부 확률 분포와 독립적으로 그린 ​​음이 아닌 부동 소수점 숫자의 목록이 제공됩니다. 당신의 임무는 숫자에서 그 분포를 유추하는 것입니다. 챌린지를 실현하기 위해 선택할 수있는 배포판은 5 개뿐입니다.

위의 모든 분포는 정확히 1/2을 의미합니다.

작업

입력은 음수가 아닌 부동 소수점 숫자의 배열이며 길이는 75에서 100 사이입니다. UTBEG위의 분포들 중 어느 것이 숫자에서 나오는지 에 따라 당신의 결과는 문자 중 하나가 될 것입니다 .

규칙과 채점

전체 프로그램이나 기능을 제공 할 수 있습니다. 표준 허점은 허용되지 않습니다.

에서 이 저장소 , 다섯 개 텍스트 파일, 각 배포 한 긴 각 정확히 100 선이있다. 각 줄에는 쉼표로 구분 된 75-100 개의 부동 소수점 목록이 분포와 독립적으로 그려지며 소수점 다음 7 자리로 잘립니다. 언어의 기본 배열 형식과 일치하도록 구분 기호를 수정할 수 있습니다. 답을 얻으려면 프로그램이 각 파일에서 50 개 이상의 목록을 올바르게 분류해야합니다 . 유효한 답변의 점수는 바이트 수 + 잘못 분류 된 총 목록 수입니다 . 가장 낮은 점수가 이깁니다.



답변

줄리아, 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감마 분포 여야하는 G.txt의 13 번째 행이 지수로 결정됨을 의미 함) 분포, 표준 편차는 0.35008999 …)

각 파일 다음에는 해당 파일에 대한 불일치 수도 출력 한 다음 총 불일치도 표시됩니다 (위와 같이 실행하면 2를 읽어야 함). 또한 G.txt와 1이 일치하지 않고 U.txt와 1이 일치하지 않아야합니다.


답변

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 무작위 샘플입니다. P (D = d | X = x)가 5보다 크도록 d를 선택합니다.

평평한 선행 (즉, [1,5]에서 i의 경우 P (D = di) = 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))]
}

ungolfed 버전은 분모를 제거하면 베타 분포가 (0,1, 1)-샘플 데이터와 동일합니다. 추가 if 문이이를 처리하지만 설명을위한 목적으로 만 알고리즘의 핵심이 아닌 복잡성을 추가 할 가치는 없습니다.

추가 코드 축소에 대한 @Alex A.에게 감사합니다. 특히 which.max!


답변

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) 에 있다면, 우리에게는 3 가지 가능성이 있습니다.

    나머지 분포는 평균에 가까운 샘플 값의 백분율 ( 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.


답변

Matlab, 428328 바이트 + 33 잘못 분류

이 프로그램은 기본적으로 실제 CDF와 데이터가 주어진 추정치를 비교 한 다음 그 둘 사이의 평균 거리를 계산합니다.

여기에 이미지 설명을 입력하십시오

이 이미지에 표시된 데이터는 청록색 분포에 속한다는 것을 명확하게 보여줍니다. 이것은 기본적으로 내 프로그램이 수행하는 것입니다. 아마 좀 더 골프를 칠 수 있습니다. 저에게는 이것이 골프가 아닌 개념적인 도전이었습니다.

이 접근 방식은 선택한 pdf 와도 독립적이며 모든 배포 세트에서 작동합니다 .

다음 코드 (폐기 됨)는 어떻게 수행되는지 보여 주어야합니다. 골프 버전은 아래와 같습니다.

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)


답변

Perl, 119 바이트 + 8 개의 잘못된 분류 = 127

세 가지 기능에 대한 작은 결정 트리를 만들었습니다.

  • $ o : 부울 : 샘플이 1.0보다 크면
  • $ t : 카운트 : 0-1 범위로 클리핑 된 0에서 6 번째 13-ile
  • $ h : 카운트 : 0에서 6까지 + 12에서 13 일까지 0-1 범위로 클리핑

을 (를) 호출했습니다 perl -F, -lane -e '...'. 비표준 매개 변수에 대해 패널티를 추가해야하는지 잘 모르겠습니다. 쉼표가 공백이면 -F 없이 자리를 비 웠을 수 있습니다.

for (@F) {$ b [$ _ * 13] ++; $ o ++ if $ _> 1}
$ h = ($ t = $ b [0]-$ b [6]) + $ b [12];
print $ o? ($ t> -2? "e": "g") : ($ h = 19? "b": "u"));
$ o = @ b = ()

약간 형식화 된 출력 (-l 플래그없이)은 다음과 같습니다.

bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
    bbbbbbbbbbbbbbbbbbbbbbbbbbubbbbbbbbbbbbbbbbbbbbbbbbb
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
    eeegeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
gggggggegggggggggggggggggggggggggggggggggggggggggggggggg
    gggggggggggggggggggggggggggggggggggggggggggggggggggg
tttttttttttttttttttttttttttttttttttttttttttttttttttttttttt
    tttttttttttttttttttttttttttttttuttttttttttttutttttt
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuutuuuuuuuuuuuuuuuubuuuuuuu
    uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuutuuuu


답변

파이썬, 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)

아이디어 : 분포는 Kolmogorov-Smirnov 검정의 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


답변