जटिलता मुक्त कोलमोगोरोव (-स्मिरनोव)


12

आंकड़ों में, कभी-कभी यह जानना उपयोगी होता है कि क्या दो डेटा नमूने एक ही अंतर्निहित वितरण से आते हैं। ऐसा करने का एक तरीका दो-नमूना कोलमोगोरोव-स्मिर्नोव परीक्षण का उपयोग करना है

आपका कार्य एक प्रोग्राम लिखना होगा जो दो बिना पढ़े हुए नॉनवेजेटिव पूर्णांक सरणियों में पढ़ता है और परीक्षण में प्रयुक्त मुख्य आँकड़ा की गणना करता है।


एक सरणी को देखते हुए Aऔर एक वास्तविक संख्या x, वितरण समारोह को परिभाषित Fद्वारा

F(A,x) = (#number of elements in A less than or equal to x)/(#number of elements in A)

दो सरणियों दिया A1और A2, परिभाषित

D(x) = |F(A1, x) - F(A2, x)|

दो-नमूना Kolmogorov-Smirnov आँकड़ा Dसभी वास्तविक पर अधिकतम मूल्य है x

उदाहरण

A1 = [1, 2, 1, 4, 3, 6]
A2 = [3, 4, 5, 4]

फिर:

D(1) = |2/6 - 0| = 1/3
D(2) = |3/6 - 0| = 1/2
D(3) = |4/6 - 1/4| = 5/12
D(4) = |5/6 - 3/4| = 1/12
D(5) = |5/6 - 4/4| = 1/6
D(6) = |6/6 - 4/4| = 0

दो सरणियों के लिए KS-आँकड़ा 1/2, का अधिकतम मूल्य है D

परीक्षण के मामलों

[0] [0] -> 0.0
[0] [1] -> 1.0
[1, 2, 3, 4, 5] [2, 3, 4, 5, 6] -> 0.2
[3, 3, 3, 3, 3] [5, 4, 3, 2, 1] -> 0.4
[1, 2, 1, 4, 3, 6] [3, 4, 5, 4] -> 0.5
[8, 9, 9, 5, 5, 0, 3] [4, 9, 0, 5, 5, 0, 4, 6, 9, 10, 4, 0, 9] -> 0.175824
[2, 10, 10, 10, 1, 6, 7, 2, 10, 4, 7] [7, 7, 9, 9, 6, 6, 5, 2, 7, 2, 8] -> 0.363636

नियम

  • आप एक समारोह या एक पूर्ण कार्यक्रम लिख सकते हैं। इनपुट STDIN या फ़ंक्शन तर्क के माध्यम से हो सकता है, और आउटपुट STDOUT या वापसी मान के माध्यम से हो सकता है।
  • आप इनपुट के लिए किसी भी अस्पष्ट सूची या स्ट्रिंग प्रारूप को मान सकते हैं, जब तक कि यह दोनों सरणियों के लिए संगत है
  • इस अवसर पर कि आपकी भाषा में इसके लिए एक बेसिन है, आप इसका उपयोग नहीं कर सकते हैं।
  • उत्तर को कम से कम 3 महत्वपूर्ण आंकड़ों के सही होने की आवश्यकता है
  • यह , इसलिए सबसे कम बाइट्स में कार्यक्रम जीत जाता है

क्या सभी इनपुट पूर्णांक सरणियाँ होने जा रहे हैं, या क्या उनमें फ्लोटिंग पॉइंट हो सकते हैं?
kennytm

@ केनीटीएम सिर्फ अप्रतिष्ठित पूर्णांक। मुझे लगा कि मैं चीजों को सरल रखूंगा।
Sp3000

क्या कोई अधिकतम मूल्य है जो हम सरणियों के लिए मान सकते हैं? (जैसे Aनीचे की सभी प्रविष्टियाँ हैं length(A)?)
दोष

@flawr नहीं आप अधिकतम मान नहीं ले सकते
Sp3000

मुझे शीर्षक पसंद है। मैं इस बार नहीं बल्कि कोलमोगोरोव जटिलता बैगदे को निशाना बना रहा हूं।
edc65

जवाबों:


10

एपीएल ( 29 24)

(अतिरिक्त प्रेरणा के लिए जरगब को धन्यवाद।)

{⌈/|-⌿⍺⍵∘.(+/≤÷(⍴⊣))∊⍺⍵}

यह एक फ़ंक्शन है जो सरणियों को अपने बाएं और दाएं तर्कों के रूप में लेता है।

      8 9 9 5 5 0 3 {⌈/|-⌿⍺⍵∘.(+/≤÷(⍴⊣))∊⍺⍵} 4 9 0 5 5 0 4 6 9 10 4 0 9 
0.1758241758

स्पष्टीकरण:

{⌈/                                maximum of
   |                               the absolute value of
    -⌿                             the difference between
      ⍺⍵∘.(         )∊⍺⍵          for both arrays, and each element in both arrays
            +/≤                    the amount of items in that array ≤ the element
               ÷                   divided by
                (⍴⊣)              the length of that array
                          }

मुझे नहीं पता था कि तुम कर सकते हो ⍺⍵! यह आसान है।
ज़गरब

1
इसके अलावा, मुझे लगता ⍳⌈/है कि अनावश्यक है, क्योंकि अधिकतम सरणी मूल्यों में से एक पर वास्तव में प्राप्त किया जाता है।
जर्ग्बेल

@Zbb: तुम बिल्कुल सही हो, मुझे बस प्रत्येक संभावित सरणी मान के लिए परीक्षण करना है। इसका मतलब है कि मैं 0,भी छुटकारा पा सकता हूं , क्योंकि यह उस के लिए परीक्षण करेगा यदि सरणी में यह है। धन्यवाद! (और वह मुझे सिखाएगा, जैसा कि आमतौर पर अगर आपको एक विशेष मामले में जोड़ना है, तो इसका मतलब है कि एल्गोरिथ्म काफी सरल नहीं है।)
मेरिनस

2
यह सच्चा जादू है, यहीं।
स्टीवन लू

@ Sp3000: क्या आपने एक-तत्व सरणियों को सही तरीके से लिखा था? आप सिर्फ लिख नहीं सकते 1, क्योंकि यह एक अदिश होगा। आपको (,1)इसके बजाय लिखना चाहिए। यदि आप ऐसा करते हैं, तो यह काम करता है।
मेरिनस

4

जे - 39

मुझे यकीन है कि इसे और अधिक छोटा किया जा सकता है

f=:+/@|:@(>:/)%(]#)
>./@:|@((,f])-(,f[))

प्रयोग

2 10 10 10 1 6 7 2 10 4 7 >./@:|@((,f])-(,f[)) 7 7 9 9 6 6 5 2 7 2 8
0.363636

क्या यह एक समारोह बनाता है या स्टड / स्टडआउट का उपयोग करता है? दूसरा भाग वास्तव में क्या करता है? (एक फ़ंक्शन कॉल के लिए थोड़ा लंबा लगता है?)
दोष

@flawr एक समारोह, एपीएल के समान
बेंत की मार

मुझे लगता है कि आप स्पष्ट रूप से परिभाषित करने से बच सकते हैं fयदि आप कुछ का उपयोग करते हैं, >./@:|@({.-{:)f"1@,लेकिन मुझे यकीन नहीं है।
फ़ूजएक्सएक्सएल

4

अजगर 3, 132 108 95 88

f=lambda a,x:sum(n>x for n in a)/len(a)
g=lambda a,b:max(abs(f(a,x)-f(b,x))for x in a+b)

इनपुट फ़ंक्शन की 2 सूचियाँ हैं g

इसके लिए धन्यवाद: Sp3000, xnor, भूमिगत शिखर

पंक्ति 2, पहले f"फ़ैक्स" जैसे रीड्स पर कॉल करें । मैंने पाया कि हल्के से मनोरंजक


2
किसी संपत्ति को संतुष्ट करने वाले सूची के तत्वों की संख्या की गणना करना, यह करने के लिए कम है sum(n>x for n in a)। इसके अलावा, ऐसा लगता है कि आप उपयोग नहीं कर रहे हैं s=filter। और इसके लिए max, आपको वास्तव में सूची कोष्ठक की आवश्यकता नहीं है; पायथन फंक्शन पैरेन्स को कॉम्प्रिहेंशन पैरेंस के रूप में डबल करने देता है।
xnor 23

धन्यवाद! मैंने filterपिछले संस्करण में उपयोग किया था, इसे निकालना भूल गया। अफसोस की बात है कि मैं वर्ग ब्रैकेट की पहली जोड़ी को हटा नहीं सकता हूं क्योंकि यह एक जनरेटर होगा, जिसमें कोई नहीं है len
Kroltan

आपको जरूरत नहीं है len, टिप्पणी को फिर से पढ़ें: पी
अंडरग्राउंडोरेल

3

जावास्क्रिप्ट (ईएस 6) 99 119 128

अधिक या कम सीधा जावास्क्रिप्ट कार्यान्वयन , शायद अधिक गोल्फ है । F फ़ंक्शन में मैं <के बजाय <= का उपयोग करता हूं, जैसे (F (a) -F (b)) === abs ((1-F (a)) - (1-F (b)))

इस अंतिम संपादन में डिफ़ॉल्ट पैरामीयर के रूप में कोई और कार्य परिभाषा नहीं है।

जैसा कि मैंने कहा, यह सीधा है। F फ़ंक्शन F फ़ंक्शन है, D फ़ंक्शन लाइन 2 में उपयोग किया जाने वाला अनाम फ़ंक्शन है। इसका उपयोग दो सरणियों में मौजूद प्रत्येक मान के लिए .map का उपयोग करके किया जाता है, क्योंकि allवास्तविक के लिए अधिकतम मान इनमें से एक होना चाहिए। अंत में, प्रसार ऑपरेटर (...) का उपयोग डी मान सरणी को अधिकतम फ़ंक्शन के पैरामीटर सूची के रूप में पास करने के लिए किया जाता है।

K=(a,b)=>Math.max(...a.concat(b).map(x=>
  Math.abs((F=a=>a.filter(v=>v>x).length/a.length)(a)-F(b))
))

FireFox / FireBug कंसोल में टेस्ट करें

;[[[0],[0]], [[0],[1]],
[[1, 2, 3, 4, 5],[2, 3, 4, 5, 6]],
[[3, 3, 3, 3, 3],[5, 4, 3, 2, 1]],
[[1, 2, 1, 4, 3, 6],[3, 4, 5, 4]],
[[8, 9, 9, 5, 5, 0, 3],[4, 9, 0, 5, 5, 0, 4, 6, 9, 10, 4, 0, 9]],
[[2, 10, 10, 10, 1, 6, 7, 2, 10, 4, 7],[7, 7, 9, 9, 6, 6, 5, 2, 7, 2, 8]]]
.forEach(x=>console.log(x[0],x[1],K(x[0],x[1]).toFixed(6)))

उत्पादन

[0] [0] 0.000000
[0] [1] 1.000000
[1, 2, 3, 4, 5] [2, 3, 4, 5, 6] 0.200000
[3, 3, 3, 3, 3] [5, 4, 3, 2, 1] 0.400000
[1, 2, 1, 4, 3, 6] [3, 4, 5, 4] 0.500000
[8, 9, 9, 5, 5, 0, 3] [4, 9, 0, 5, 5, 0, 4, 6, 9, 10, 4, 0, 9] 0.175824
[2, 10, 10, 10, 1, 6, 7, 2, 10, 4, 7] [7, 7, 9, 9, 6, 6, 5, 2, 7, 2, 8] 0.363636

मैं आपके कार्य के बारे में उत्सुक हूं K: क्या यह सही है कि आप F,Dतर्क सूची में अन्य कार्यों को परिभाषित करते हैं ? क्या यह कुछ वैकल्पिक तर्कों की तरह है?
दोष

@flawr हाँ, वे एक डिफ़ॉल्ट मान के साथ वैकल्पिक तर्क हैं। तो वैश्विक चर स्थान के प्रदूषण से बचना (यह कोड गोल्फ में कोई समस्या नहीं है, लेकिन वैसे भी ...)
edc65

1
साथ ही, चूंकि फ़ंक्शन को पहले से ही 2 वेरिएबल्स (इस प्रकार ब्रैकेट्स) की आवश्यकता थी, इसलिए फ़ंक्शन बॉडी के अंदर उन वेरिएबल्स को ऑप्शन वर्जन सूची से बाहर ले जाने के लिए 2 अतिरिक्त बाइट्स होंगे।
अनुकूलक


2

मतलाब (121) (119)

यह एक ऐसा प्रोग्राम है जो दो सूचियों को काटता है और परिणाम को स्टडआउट करता है। यह एक स्ट्रेटफीड एप्रोच है और मैंने इसे जितना संभव हो उतना गोल्फ करने की कोशिश की। K(a)एक फ़ंक्शन देता है जो गणना करता है x -> F(a,x)। फिर फ़ंक्शन के @(x)abs(g(x)-h(x))अनुरूप होने वाले अनाम फ़ंक्शन Dको हर संभव पूर्णांक पर लागू किया जाता है 0:max([a,b])और अधिकतम परिणाम प्रदर्शित किया जाता है। ( अन्य भाषाओं arrayfunकी तरह ही है map: यह एक एरे के प्रत्येक तत्व पर एक फंक्शन लागू करता है)

a=input('');b=input('');
K=@(a)@(x)sum(a<=x)/numel(a);
g=K(a);h=K(b);
disp(max(arrayfun(@(x)abs(g(x)-h(x)),0:max([a,b]))))

2

एर्लैंग, 96 बाइट्स

edc65 के जावास्क्रिप्ट समाधान को Erlang में पोर्ट किया गया।

f(A,B)->F=fun(A,X)->length([V||V<-A,V>X])/length(A)end,lists:max([abs(F(A,X)-F(B,X))||X<-A++B]).

परीक्षा:

lists:foreach(fun ([H,T] = L) -> io:format("~p ~p~n", [L, w:f(H, T)]) end, [[[0],[0]], [[0],[1]],
        [[1, 2, 3, 4, 5],[2, 3, 4, 5, 6]],
        [[3, 3, 3, 3, 3],[5, 4, 3, 2, 1]],
        [[1, 2, 1, 4, 3, 6],[3, 4, 5, 4]],
        [[8, 9, 9, 5, 5, 0, 3],[4, 9, 0, 5, 5, 0, 4, 6, 9, 10, 4, 0, 9]],
        [[2, 10, 10, 10, 1, 6, 7, 2, 10, 4, 7],[7, 7, 9, 9, 6, 6, 5, 2, 7, 2, 8]]]).

आउटपुट:

[[0],[0]] 0.0
[[0],[1]] 1.0
[[1,2,3,4,5],[2,3,4,5,6]] 0.20000000000000007
[[3,3,3,3,3],[5,4,3,2,1]] 0.4
[[1,2,1,4,3,6],[3,4,5,4]] 0.5
[[8,9,9,5,5,0,3],[4,9,0,5,5,0,4,6,9,10,4,0,9]] 0.17582417582417587
[[2,10,10,10,1,6,7,2,10,4,7],[7,7,9,9,6,6,5,2,7,2,8]] 0.36363636363636365

2

STATA 215

यह 90% इनपुट को एक प्रारूप में प्राप्त करना है जिसका उपयोग किया जा सकता है क्योंकि STATA में पहले से ही ksmirnov कमांड है।

di _r(a)
di _r(b)
file open q using "b.c",w
forv x=1/wordcount($a){
file w q "1,"(word($a,`x'))_n
}
forv x=1/wordcount($b){
file w q "2,"(word($b,`x'))_n
}
file close q
insheet using "b.c"
ksmirnov v2,by(v1)
di r(D)

अरे वाह, मैंने यह नहीं सोचा था कि इसके लिए भाषाओं का निर्माण होगा ... मैंने अभी कुछ शोध किया है और मैंने फैसला किया कि अब से बिलिनों को समाप्त करना सबसे अच्छा होगा, लेकिन आप इसे रख सकते हैं क्योंकि यह नियम से पहले पोस्ट किया गया था परिवर्तन :)
२:११ पर २३०००

2

आर, 65 बाइट्स

f=function(a,b){d=c(a,b);e=ecdf(a);g=ecdf(b);max(abs(e(d)-g(d)))}

यह फ़ंक्शन दो वैक्टरों को तर्क के रूप में लेता है और उनके अनुभवजन्य संचयी वितरण कार्यों का अधिकतम अंतर लौटाता है।

यदि बिल्ट-इन की अनुमति दी गई है, तो यह केवल 12 बाइट्स तक कम हो जाएगा:

ks.test(a,b)

1

मैथमेटिका, 76 73 63

Mathematica में अंतर्निहित फ़ंक्शन है KolmogorovSmirnovTest, लेकिन मैं इसका उपयोग यहां नहीं करूंगा।

k=N@MaxValue[Abs[#-#2]&@@(Tr@UnitStep[x-#]/Length@#&/@{##}),x]&

उपयोग:

k[{1, 2, 1, 4, 3, 6}, {3, 4, 5, 4}]

0.5


0

पायथन 3.4.2 (79 बाइट्स) में त्वरित कार्यान्वयन:

F=lambda A,x:len([n for n in A if n<=x])/len(A)
D=lambda x:abs(F(A1,x)-F(A2,x))

उदाहरण:

>>> A1 = [-5, 10, 8, -2, 9, 2, -3, -4, -4, 9]
>>> A2 = [-5, -3, -10, 8, -4, 1, -7, 6, 9, 5, -7]
>>> D(0)
0.045454545454545414

1
आवश्यकता है कि सभी पूर्णांक मानों के लिए D (x) का अधिकतम मान ज्ञात किया जाए। कृपया समस्या युक्ति का अनुपालन करें।
ऑप्टिमाइज़र

1
स्वागत हे! जैसा कि ऑप्टिमाइज़र कहता है, कार्य का अधिकतम मूल्य खोजना है D, न कि केवल Dएक फ़ंक्शन के रूप में लागू करना। इसके अलावा, मुझे खेद है कि अगर मैं स्पष्ट नहीं था, लेकिन आप यह मान नहीं सकते हैं A1और A2पहले से ही परिभाषित चर हैं (आप उन्हें lambda x,A1,A2:
लंबो

इसके अलावा, मैंने कुछ वाक्य रचना हाइलाइटिंग जोड़ दी है - मुझे लगता है कि यह इसे सुंदर दिखता है :)
Sp3000

इसके बारे में क्षमा करें, मैं यहां नया हूं।
कप्तानन

कोई समस्या नहीं :) अगर कुछ भी अस्पष्ट है, तो आप टिप्पणियों में पूछ सकते हैं। लेकिन एक बार फिर, आपका स्वागत है!
Sp3000

0

जावा - 633 622 बाइट्स

ठीक है, पहले, जावा में बेहतर होने की कोशिश कर रहा है इसलिए मैंने इसे जावा में क्यों आज़माया, मुझे पता है कि मैं कभी भी अच्छा नहीं करूँगा, लेकिन एह, इसका मज़ा। दूसरा, मैंने ईमानदारी से सोचा था कि मैं इसे कम तरीके से कर सकता हूं, फिर मैं उस मंच पर पहुंच गया जहां हर जगह युगल थे, और विधि घोषणाओं का मतलब था कि केवल तरीकों का उपयोग करके कुल 4-5 चार्ट बचाए गए। संक्षेप में, मैं एक बुरा गोल्फ खिलाड़ी हूं।

संपादित करें: उपयोग प्रारूप> जावा K "2,10,10,10,1,6,7,2,10,4,7" "7,7,9,9,6,6,5,2,2,2,2 , 8 "

import java.lang.*;
class K{public static void main(String[]a){double[]s1=m(a[0]);double[]s2=m(a[1]);
int h=0;if(H(s1)<H(s2))h=(int)H(s2);else h=(int)H(s1);double[]D=new double[h];
for(int i=0;i<h;i++){D[i]=Math.abs(F(s1,i)-F(s2,i));}System.out.println(H(D));}
static double[]m(String S){String[]b=S.split(",");double[]i=new double[b.length];
for(int j=0;j<b.length;j++){i[j]=new Integer(b[j]);}return i;}
static double H(double[]i){double t=0;for(int j=0;j<i.length;j++)
{if(i[j]>t)t=i[j];}return t;}
static double F(double[]A,int x){double t=0;double l=A.length;
for(int i=0;i<l;i++){if(A[i]<=x)t++;}return t/l;}}

तुम सही थे। अद्यतन।
ब्रायन देवनय 16

0

हास्केल 96 83

l=fromIntegral.length
a%x=l(filter(<=x)a)/l a
a!b=maximum$map(\x->abs$a%x-b%x)$a++b

(!) kolmogorov-smirnov फ़ंक्शन है जो दो सूचियों को लेता है


1
कुछ त्वरित गोल्फ: mapबजाय उपयोग fmap; के maximumबजाय का उपयोग करें foldr1 max; परिभाषित l=fromIntegral.lengthऔर आप से छुटकारा मिल सकता है i, और फिर आप को छोटा कर सकते %करने के लिए l(filter(<=x)a)/l a। यह 84 हो जाता है!
MtnViewMark

0

आर, 107 बाइट्स

अलग दृष्टिकोण

f=function(a,b){e=0
d=sort(unique(c(a,b)))
for(i in d-min(diff(d))*0.8)e=max(abs(mean(a<i)-mean(b<i)),e)
e}

Ungolfed

f=function(a,b){
    e=0
    d=sort(unique(c(a,b)))
    d=d-min(diff(d))*0.8
    for(i in d) {
        f=mean(a<i)-mean(b<i)
        e=max(e,abs(f))
    }
    e
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.