Ai là người phân phối xác suất?


16

Giới thiệu

Trong thử thách này, bạn được cung cấp một danh sách các số dấu phẩy động không âm được rút ra độc lập với một số phân phối xác suất. Nhiệm vụ của bạn là suy ra sự phân phối đó từ những con số. Để làm cho thử thách khả thi, bạn chỉ có năm bản phân phối để lựa chọn.

Lưu ý rằng tất cả các bản phân phối ở trên có nghĩa chính xác là 1/2.

Nhiệm vụ

Đầu vào của bạn là một dãy các số dấu phẩy động không âm, có độ dài từ 75 đến 100. Đầu ra của bạn sẽ là một trong những chữ cái UTBEG, dựa trên phân phối trên mà bạn đoán các số được rút ra từ đó.

Quy tắc và chấm điểm

Bạn có thể cung cấp một chương trình đầy đủ hoặc một chức năng. Sơ hở tiêu chuẩn là không được phép.

Trong kho lưu trữ này , có năm tệp văn bản, một tệp cho mỗi phân phối, mỗi tệp dài chính xác 100 dòng. Mỗi dòng chứa một danh sách được phân tách bằng dấu phẩy gồm 75 đến 100 số float được vẽ độc lập với phân phối và được rút ngắn thành 7 chữ số sau dấu thập phân. Bạn có thể sửa đổi các dấu phân cách để phù hợp với định dạng mảng gốc của ngôn ngữ của bạn. Để đủ điều kiện là một câu trả lời, chương trình của bạn nên phân loại chính xác ít nhất 50 danh sách từ mỗi tệp . Điểm của một câu trả lời hợp lệ là số byte + tổng số danh sách bị phân loại sai . Điểm thấp nhất sẽ thắng.


Tôi có lẽ nên hỏi sớm hơn, nhưng dự kiến ​​sẽ tối ưu hóa bao nhiêu cho các trường hợp thử nghiệm? Tôi đang ở một điểm mà tôi có thể cải thiện điểm số của mình bằng cách điều chỉnh một vài thông số, nhưng tác động đến điểm số có thể sẽ phụ thuộc vào các trường hợp kiểm tra nhất định.
Dennis

2
@Dennis Bạn có thể tối ưu hóa bao nhiêu tùy ý, các trường hợp thử nghiệm là một phần cố định của thử thách.
Zgarb

YU KHÔNG phân phối sinh viên-t? = (
N3buchadnezzar

Câu trả lời:


6

Julia, 60 62 byte + 25 2 lỗi = 82 64

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

Điều này khá đơn giản. Phương sai của các bản phân phối hầu hết là khác nhau - đó là 1/4 cho số mũ, 1/8 cho beta, 1/12 cho gamma và đồng phục và 1/24 cho tam giác. Như vậy, nếu chúng ta sử dụng phương sai (ở đây được sử dụng stdcho độ lệch chuẩn, căn bậc hai của phương sai) để xác định phân phối có khả năng, chúng ta chỉ cần làm nhiều hơn để phân biệt gamma với thống nhất; để làm điều đó, chúng tôi tìm kiếm một giá trị lớn hơn 1 (sử dụng any(k.>1)) - có nghĩa là, chúng tôi thực hiện kiểm tra cả theo cấp số nhân và gamma, vì nó cải thiện hiệu suất tổng thể.

Để lưu một byte, lập chỉ mục chuỗi "EGTBU"được thực hiện thay vì đánh giá trực tiếp thành một chuỗi trong các điều kiện.

Để kiểm tra, hãy lưu các tệp txt vào một thư mục (giữ nguyên tên) và chạy Julia REPL trong thư mục đó. Sau đó, gắn hàm vào một tên như

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

và sử dụng đoạn mã sau để tự động kiểm tra (điều này sẽ đọc từ tệp, chuyển đổi thành một mảng các mảng, sử dụng hàm và đầu ra cho mỗi lần không khớp):

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)

Đầu ra sẽ bao gồm các hàng chứa trường hợp không khớp, phân phối chính xác -> phân phối xác định và phương sai được tính (ví dụ: 13 G->E 0.35008999281668357hàng thứ 13 trong G.txt, phải là phân phối gamma, được xác định là số mũ phân phối, với độ lệch chuẩn là 0.35008999 ...)

Sau mỗi tệp, nó cũng xuất ra số lượng không khớp cho tệp đó, và cuối cùng, nó cũng hiển thị tổng số không khớp (và nó sẽ đọc 2 nếu chạy như trên). Ngẫu nhiên, cần có 1 không khớp cho G.txt và 1 không khớp cho U.txt


7

R, 202 192 184 182 162 154 byte + 0 lỗi

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

Điều này dựa trên công thức Bayes P (D = d | X = x) = P (X = x | D = d) * P (D = d) / P (X = x), trong đó D là phân phối và X là mẫu ngẫu nhiên. Chúng tôi chọn d sao cho P (D = d | X = x) là lớn nhất trong 5.

Tôi giả sử một căn hộ trước (nghĩa là P (D = di) = 1/5 cho i trong [1,5]), có nghĩa là P (D = d) trong tử số là giống nhau trong mọi trường hợp (và mẫu số sẽ dù sao cũng giống nhau trong mọi trường hợp), vì vậy chúng ta có thể đánh gôn mọi thứ trừ P (x = X | D = d), ngoại trừ phân phối tam giác) đơn giản hóa các hàm riêng trong R.

vô dụng:

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))]
}

Lưu ý rằng phiên bản không được chỉnh sửa không tương đương chính xác với phiên bản được đánh gôn vì việc loại bỏ mẫu số sẽ tránh trường hợp Inf / Inf xảy ra nếu bạn cho phép phân phối beta vượt quá khoảng thời gian đóng [0,1] thay vì (0, 1) - như dữ liệu mẫu. Một câu lệnh if bổ sung sẽ xử lý điều đó nhưng vì nó chỉ nhằm mục đích minh họa nên có lẽ không đáng để thêm độ phức tạp không nằm ở trung tâm của thuật toán.

Cảm ơn @Alex A. để giảm mã bổ sung. Đặc biệt là which.max!


1
Bạn có thể nhận được tới 190 byte bằng cách xóa ngắt dòng sau khi mở {và trước khi đóng }và bí danh prod, ví dụ P=prod, sau đó thực hiện P(dunif(x)), v.v. Hàm không cần tên để gửi hợp lệ, vì vậy bạn có thể xóa p=. Ngoài ra, công việc tuyệt vời. :)
Alex A.

2
Bạn có thể đưa nó đến 182 bằng cách sử dụng các đề xuất trên và sử dụng which.max(c(u,r,b,e,g))thay thế c(u,r,b,e,g)==max(c(u,r,b,e,g)).
Alex A.

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))]}
Alex A.

Sao bạn dám sử dụng R cho một thử thách liên quan đến thống kê !!
flawr

6

CJam, 76

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

Mã nguồn dài 43 byte và phân loại sai 33 danh sách.

xác minh

$ 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

Ý tưởng

Phân biệt phân phối theo cấp số nhân và gamma với các phân phối còn lại là dễ dàng, vì chúng là phân phối duy nhất có giá trị lớn hơn 1 .

Để quyết định giữa gamma , hàm mũ và các số khác, chúng ta hãy xem giá trị cao thứ hai của mẫu.

  • Nếu nó nằm trong [1,5,) , chúng tôi đoán gamma .

  • Nếu nó nằm trong [1, 1.5) , chúng tôi đoán theo cấp số nhân .

  • Nếu nó nằm trong [0, 1) , chúng ta có ba khả năng còn lại.

    Các phân phối còn lại có thể được phân biệt bằng tỷ lệ phần trăm của các giá trị mẫu nằm gần với giá trị trung bình ( 0,5 ).

    Chúng tôi chia chiều dài của mẫu cho số lượng giá trị nằm trong (0,3, 0,7) và xem xét thương số kết quả.

    • Nếu nó nằm trong (1, 2] , chúng tôi đoán hình tam giác .

    • Nếu nó nằm trong (2, 3] , chúng tôi đoán đồng phục .

    • Nếu nó nằm trong (3,) , chúng tôi đoán là beta .

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 byte + 33 phân loại sai

Chương trình này về cơ bản là so sánh CDF thực với dữ liệu ước tính được cung cấp dữ liệu và sau đó tính khoảng cách trung bình giữa hai thứ đó: Tôi nghĩ rằng hình ảnh giải thích thêm:

nhập mô tả hình ảnh ở đây

Dữ liệu hiển thị trong hình ảnh này ở đây cho thấy khá rõ rằng nó thuộc về phân phối màu ngọc lam, vì nó khá gần với phân phối đó, vì vậy đó là cơ bản những gì chương trình của tôi đang làm. Nó có thể có thể được chơi golf nhiều hơn một chút. Đối với tôi đó trước hết là một thử thách về mặt khái niệm, không phải là rất golf.

Cách tiếp cận này cũng độc lập với các pdf được chọn, nó sẽ hoạt động cho bất kỳ bộ phân phối nào.

Theo mã (không được mã hóa) sẽ cho thấy nó được thực hiện như thế nào. Các phiên bản golf là dưới đây.

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

Phiên bản đầy đủ golf:

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 byte + 8 phân loại sai = 127

Tôi đã thực hiện một cây quyết định nhỏ trên ba tính năng:

  • $ o: boolean: nếu có mẫu> 1.0
  • $ t: tính: 0 -th trừ 6-thứ 13 được cắt vào phạm vi 0-1,
  • $ h: tính: 0 giây trừ 6 giây cộng với 13 giây được cắt vào phạm vi 0-1

Gọi với perl -F, -lane -e '...'. Tôi không chắc mình có nên thêm hình phạt cho các tham số không chuẩn hay không. Nếu dấu phẩy là khoảng trắng, tôi đoán tôi có thể thoát ra mà không có -F,

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

Đầu ra được định dạng hơi (không có cờ -l) là:

bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
    bbbbbbbbbbbbbbbbbbbbbbbbbubbbbbbbbbbbbbbbbbbbbbbbb
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
    eeegeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
gggggggegggggggggggggggggggggggggggggggggggggggggggggg
    gggggggggggggggggggggggggggggggggggggggggggggggg
tttttttttttttttttttttttttttttttttttttttttttttttttttttttt
    tttttttttttttttttttttttttttttttutttttttttttttuttttttttt
uuuuuuuuuuuuuuuuuuuuuuuuuuutuuuuuuuuuuuuuuuubuuuuuuu
    uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuutuuuu

0

Python, 318 byte + 35 lỗi phân loại

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)

Ý tưởng: phân phối được đoán dựa trên giá trị p của thử nghiệm Kolmogorov-Smirnov.

Kiểm tra

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.