2010-10-11 11 views
10

की गणना के लिए ऑनलाइन एल्गोरिदम मैं एक वेक्टर online के पूर्ण विचलन की गणना करने की कोशिश कर रहा हूं, जैसा कि पूरे वेक्टर का उपयोग किए बिना वेक्टर में प्रत्येक आइटम प्राप्त होता है।पूर्ण विचलन

\sum_{i=0}^{n-1}{{abs%28\overline{x}%20-%20x_i}%29}

मुझे पता है कि एक वेक्टर के विचरण को इस तरीके से गणना की जा सकती: निरपेक्ष विचलन एक वेक्टर में प्रत्येक आइटम के बीच पूर्ण अंतर और मतलब का योग है। विचरण निरपेक्ष विचलन के समान है, लेकिन प्रत्येक अंतर चुकता है:

इस प्रकार

\frac{\sum_{i=0}^{n-1}{{%28\overline{x}%20-%20x_i}%29}^2}{n}

विचरण के लिए ऑनलाइन एल्गोरिथ्म है:

n = 0 
mean = 0 
M2 = 0 

def calculate_online_variance(x): 
    n = n + 1 
    delta = x - mean 
    mean = mean + delta/n 
    M2 = M2 + delta*(x - mean) # This expression uses the new value of mean 
    variance_n = M2/n 
    return variance_n 

वहाँ पूर्ण की गणना के लिए इस तरह के एक एल्गोरिथ्म है विचलन? मैं खुद को एक पुनरावर्ती परिभाषा तैयार नहीं कर सकता, लेकिन बुद्धिमान सिर प्रबल हो सकते हैं!

+0

+1: दिलचस्प ऑनलाइन विचरण गणना एल्गोरिथ्म। – EOL

+1

ध्यान दें कि ओपी द्वारा दिए गए भिन्नता के लिए ऑनलाइन एल्गोरिदम एक अनुमान है। –

+1

@ जस्टिन छील सभी फ़्लोटिंग पॉइंट गणना अनुमान हैं। यह एल्गोरिदम वास्तव में अन्य दृष्टिकोणों की तुलना में कई वास्तविक दुनिया स्थितियों में अधिक सटीक है: http://www.johndcook.com/standard_deviation.html – fmark

उत्तर

1

मुझे नहीं लगता कि यह संभव है।

भिन्नता के सूत्र में x और x शर्तों को अलग करना संभव है, ताकि यह उन रकम (और n) का ट्रैक रखने के लिए पर्याप्त हो। पूर्ण विचलन के लिए सूत्र में यह संभव नहीं है।

मुझे लगता है कि सबसे अच्छा कोई भी कर सकता है (पूरे वेक्टर को रखने और मांग पर पूर्ण विचलन की गणना के अलावा) तत्वों की एक क्रमबद्ध सूची रखता है। यह प्रत्येक नए तत्व के लिए ओ (लॉग (एन)) है, लेकिन जब आप तत्व जोड़ते हैं तो पूर्ण विचलन को पुन: गणना करने की लागत ओ (लॉग (एन)) है। यह आपके आवेदन के आधार पर सार्थक हो सकता है या नहीं भी हो सकता है।

+0

क्या आप अपनी क्रमबद्ध सूची एल्गोरिदम पर विस्तृत कर सकते हैं? – fmark

1

आपके द्वारा दिए गए भिन्नता के लिए सूत्र संभव है जो कई संभव है (मैं गणना करने के तीन अलग-अलग तरीकों के बारे में सोच सकता हूं) हालांकि मैंने सत्यापित नहीं किया है कि आपका सही है। यह मुझे याद करने के लिए उचित रूप से करीब दिखता है।

समस्या यह है कि विचलन के वर्गों की तुलना में पूर्ण मूल्य वास्तव में अधिक "nonlinear" है। यह आपको लूप में एक पुनरावर्ती रूप में उस गणना को करने में सक्षम होने से रोकता है, कम से कम x के पिछले सभी मानों को बनाए रखने के बिना नहीं। आपको उस योग के लिए अग्रिम रूप से समग्र माध्य की गणना करनी होगी।

संपादित करें: मुझे लगता है कि बीटा मेरे साथ सहमत है। यदि आपने पिछले सभी बिंदुओं को एक क्रमबद्ध सूची में सहेजा है, तो आप अद्यतन वांछित विचलन को कुशलतापूर्वक गणना कर सकते हैं। लेकिन यह आपके अनुरोध की भावना का मुकाबला है।

+0

+1 मैं उम्मीद कर रहा था कि यह मामला नहीं है। जोरीस के अनुकूलन का उपयोग करना पर्याप्त होगा! – fmark

4

चूंकि एक्स और माध्य के बीच पूर्ण विचलन को वर्ग अंतर के वर्ग रूट के रूप में परिभाषित किया जा सकता है, तो अनुकूलन एक छोटा लेकिन पक्षपातपूर्ण अनुमान से खुश है (अर्थात् अनंतता की सीमा अपेक्षित मान है) :

n = 0 
mean = 0 
M2 = 0 

def calculate_online_avg_abs_dev(x): 
    n = n + 1 
    delta = x - mean 
    mean = mean + delta/n 
    M2 = M2 + sqrt(delta*(x - mean)) 
    avg_abs_dev_n = M2/n 

यह औसत पूर्ण विचलन के मामले में है। आम तौर पर पागल का उपयोग किया जाता है (औसत पूर्ण विचलन), जो पुनरावर्ती कार्यक्रम के लिए असंभव है। लेकिन औसत मामलों में औसत पूर्ण विचलन उपयोगी है। जब हम निकट-से-सामान्य वितरण से सैकड़ों मूल्यों के बारे में बात कर रहे हैं, तो दोनों मूल्य बहुत करीब हैं।

यदि आप केवल पूर्ण समर्पण की राशि चाहते हैं, तो जीवन भी आसान है: बस एम 2 लौटाएं।

इस तथ्य से अवगत रहें कि आपके द्वारा दिए गए एल्गोरिदम और पूर्ण विचलन के लिए मामूली अनुकूलन थोड़ा पक्षपातपूर्ण है।

एल्गोरिथ्म साबित करने के लिए आर में एक सिमुलेशन इस तरह से काम करता है:

alt text

लाल रेखा सही मूल्य है, काली रेखा एल्गोरिथ्म ऊपर बताई गई प्रगतिशील मूल्य है।

कोड:

calculate_online_abs_dev <- function(x,n){ 
    M2=0 
    mean=0 
    out <- numeric(n) 
    for(i in 1:n) { 
     delta <- x[i] - mean 
     mean <- mean + delta/i 
     M2 = M2 + sqrt(delta*(x[i] - mean)) 
     out[i] <- M2/i 

    } 
    return(out) 
} 

set.seed(2010) 
x <- rnorm(100) 

Abs_Dev <- calculate_online_abs_dev(x,length(x)) 
True_Val <- sapply(1:length(x),function(i)sum(abs(x[1:i]-mean(x[1:i])))/i) 

plot(1:length(x),Abs_Dev,type="l",xlab="number of values",lwd=2) 
lines(1:length(x),True_Val,col="red",lty=2,lwd=2) 
legend("bottomright",lty=c(1,2),col=c("black","red"), 
    legend=c("Online Calc","True Value")) 
+0

मैं उम्मीद कर रहा था कि कोई और अधिक परिष्कृत प्राप्त करने में सक्षम हो सकता है जो डरावनी 'sqrt' से जुड़ी त्रुटि को कम करेगा, लेकिन ऐसा लगता है कि यह सबसे अच्छा है जिसे हम प्राप्त कर सकते हैं ... – fmark

+1

@fmark: यदि आप कम कर सकते हैं मेरे सिमुलेशन में जो दिखाता है उससे ज्यादा डरावनी एसक्यूआरटी से जुड़ी त्रुटि, आपको 6 अंक और अधिक सटीक होना होगा। एन> 100 के साथ, मतभेद उपेक्षित हैं। और स्पष्ट रूप से, आपका भिन्नता एल्गोरिदम इस जैसा सटीक है, जिसे आसानी से इसी तरह के सिमुलेशन में दिखाया जाता है। कभी-कभी आपको बहुत दूर नहीं दिखना चाहिए। बड़ी संख्या में कानून इस समाधान की गारंटी देता है कि यह वास्तविक मूल्य तक पहुंच जाएगा, और यहां तक ​​कि तेज़ भी। –

+1

> बड़ी संख्या का कानून आपको परीक्षण के लिए सामान्य वितरण का उपयोग नहीं करना चाहिए - बड़ी संख्या में कानून केवल सामान्य वितरण पर लागू होता है! मैंने अधिक पक्षपातपूर्ण इनपुट की कोशिश की, उदा। (पायथन) 'श्रृंखला = [रैंडम.रंडिंट (50, 70) मैं रेंज में (33)] + [रैंडम.रंडिंट (40, 50) रेंज में (66)] ' और निम्नलिखित ग्राफ को' आर' जो वास्तविक मूल्य से अलग हो रहा है: [आर में पक्षपातपूर्ण इनपुट का आउटपुट] (http://imgur.com/SePtfhv) – EoghanM

संबंधित मुद्दे