गिनती और डेटा-कुल को रखे बिना चलती औसत की गणना कैसे करें?


118

मैं अब तक प्राप्त गणना और कुल डेटा को संग्रहीत किए बिना एक चलती संचयी औसत की गणना करने का एक तरीका खोजने की कोशिश कर रहा हूं।

मैं दो एल्गोरिदम के साथ आया था लेकिन दोनों को गणना करने की आवश्यकता है:

  • नया औसत = ((पुरानी गणना * पुराना डेटा) + अगला डेटा) / अगली गणना
  • नया औसत = पुराना औसत + (अगला डेटा - पुराना औसत) / अगली गणना

इन तरीकों के साथ समस्या यह है कि गिनती बड़ी हो जाती है और परिणामी औसत में सटीक खोने के कारण गिनती बड़ी हो जाती है।

पहली विधि पुरानी गणना और अगली गणना का उपयोग करती है जो स्पष्ट रूप से 1 अलग हैं। इससे मुझे लगा कि शायद गिनती निकालने का एक तरीका है, लेकिन दुर्भाग्य से मैंने अभी तक इसे नहीं पाया है। यह मुझे थोड़ा आगे मिला, हालांकि दूसरी विधि के परिणामस्वरूप, लेकिन अभी भी गिनती मौजूद है।

क्या यह संभव है, या मैं सिर्फ असंभव को खोज रहा हूं?


1
एनबी कि संख्यात्मक रूप से, वर्तमान कुल और वर्तमान गणना को संग्रहीत करना सबसे स्थिर तरीका है। अन्यथा, उच्च गणना के लिए अगला / (अगली गणना) कम होना शुरू हो जाएगा। तो अगर आप वास्तव में सटीक खोने के बारे में चिंतित हैं, तो योग रखें!
16

1
देखें विकिपीडिया en.wikipedia.org/wiki/Moving_aiture
xmedeko

जवाबों:


91

आप बस कर सकते हैं:

double approxRollingAverage (double avg, double new_sample) {

    avg -= avg / N;
    avg += new_sample / N;

    return avg;
}

Nउन नमूनों की संख्या कहाँ है जहाँ आप औसत से अधिक चाहते हैं। ध्यान दें कि यह सन्निकटन एक घातीय चलती औसत के बराबर है। देखें: C ++ में रोलिंग / मूविंग एवरेज की गणना करें


3
क्या आपको इस पंक्ति से पहले इसमें 1 से N नहीं जोड़ना है? avg + = new_sample / N;
डेमियन

20
यह पूरी तरह सही नहीं है। @Muis जो वर्णन करता है वह एक तेजी से भारित चलती औसत है, जो कभी-कभी उपयुक्त होता है, लेकिन ओपी द्वारा अनुरोध किए जाने पर ठीक नहीं होता है। एक उदाहरण के रूप में, उस व्यवहार पर विचार करें जिसकी आप अपेक्षा करते हैं जब अधिकांश बिंदु 2 से 4 की सीमा में हों, लेकिन एक मान एक मिलियन से ऊपर हो। एक EWMA (यहाँ) काफी समय तक उस मिलियन के निशान पर रहेगा। एक परिमित आक्षेप, जैसा कि ओपी द्वारा इंगित किया गया है, एन चरणों के तुरंत बाद इसे खो देगा। इसमें निरंतर स्टोरेज का लाभ है।
jma

9
यह एक चलती औसत नहीं है। आप जो वर्णन करते हैं वह एक पोल फ़िल्टर है जो सिग्नल में कूदने के लिए घातीय प्रतिक्रियाएं बनाता है। एक मूविंग एवरेज लंबाई के साथ एक रैखिक प्रतिक्रिया बनाता है
ruhig brauner

3
खबरदार कि यह औसत की आम परिभाषा से काफी दूर है। यदि आप N = 5 सेट करते हैं और 5 5नमूने दर्ज करते हैं, तो औसत 0.67 होगा।
डेन डैस्कलेस्कु

2
@DanDascalescu जब आप सही हैं कि यह वास्तव में एक रोलिंग औसत नहीं है, तो आपका घोषित मूल्य परिमाण के एक क्रम से बंद है। avgआरंभिक के साथ 0, आप 3.365 5एस के बाद समाप्त हो जाते हैं , और 4.4610 के बाद: cpp.sh/2ryql लंबे औसत के लिए, यह निश्चित रूप से एक उपयोगी सन्निकटन है।
सिनकोडेनदा

80
New average = old average * (n-1)/n + new value /n

यह केवल एक मान से परिवर्तित गणना मान रहा है। मामले में यह एम मानों द्वारा बदल दिया जाता है:

new average = old average * (n-len(M))/n + (sum of values in M)/n).

यह गणितीय सूत्र है (मेरा मानना ​​है कि सबसे कुशल एक), विश्वास है कि आप अपने द्वारा आगे कोड कर सकते हैं


नए मूल्य का योग क्या है? क्या आपके मूल सूत्र में "नए मूल्य" से किसी तरह अलग है?
मिखाइल

@ मिखाइल दूसरे उदाहरण में, mनए मूल्यों को नए औसत में विभाजित किया जा रहा है। मेरा मानना ​​है कि sum of new valueयहां mनए मूल्यों की गणना करने के लिए इस्तेमाल किए जा रहे नए मूल्यों का योग है ।
पैट्रिक गोले

9
पहले एक के लिए थोड़ा अधिक कुशल: new_average = (old_average * (n-1) + new_value) / n- विभाजन में से एक को हटाता है।
Pixelstix

6,0,0,9 के साथ 3 तत्वों के औसत चलने के बारे में कैसे?
रोशन मेहता

1
जब मैं इस समीकरण को लागू करता हूं तो मूल्य या चल औसत हमेशा धीरे-धीरे बढ़ता है। यह कभी नीचे नहीं जाता - केवल ऊपर।
अनोन

30

नमूना विचरण गणना पर एक ब्लॉग से , जहां वेलफ़ोर्ड की विधि का उपयोग करके माध्य की भी गणना की जाती है :

यहां छवि विवरण दर्ज करें

बहुत बुरा हम SVG चित्र अपलोड नहीं कर सकते।


3
यह मुईस द्वारा लागू किए गए समान है, सिवाय इसके कि विभाजन को एक सामान्य कारक का उपयोग किया जाता है। इस प्रकार केवल एक विभाजन।
फ्लिप करें

यह वास्तव में @ अब्दुल्ला-अल-एजेल (अनिवार्य रूप से कम्यूटेटिव गणित) के करीब है कि म्यूइस एन को बढ़ाने के लिए खाता नहीं है; कॉपी-पेस्ट सूत्र संदर्भ: [n पर औसत] = [n-१ पर औसत] + (x - [n-१ पर औसत]] / n
२०:१६ पर drzaus

2
@ फील एंड ड्रॉउंस: ऐन माइस और अब्दुल्ला अल-एजेल समाधान बिल्कुल समान नहीं हैं? यह एक ही संगणना है, बस अलग तरह से लिखा गया है। मेरे लिए वे 3 उत्तर पहचान योग्य हैं, यह एक अधिक दृश्य है (बहुत बुरा हम एसओ पर MathJax का उपयोग नहीं कर सकते हैं)।
user276648

21

यहाँ कैसे पर अभी तक एक और जवाब भेंट कमेंटरी है Muis , अब्दुल्ला अल-Ageel और फ्लिप के जवाब हैं सभी गणितीय एक ही बात अलग ढंग से लिखा छोड़कर।

ज़रूर, हमारे पास जोस मैनुअल रामोस हैं का विश्लेषण है, जिसमें बताया गया है कि कैसे गोलाई की त्रुटियां प्रत्येक थोड़ा अलग तरीके से प्रभावित करती हैं, लेकिन यह कार्यान्वयन पर निर्भर है और प्रत्येक उत्तर को कोड में कैसे लागू किया जाता है, इसके आधार पर परिवर्तन होगा।

हालांकि एक बड़ा अंतर है

क्या है Muis की N, फ्लिप की k, और अब्दुल्ला अल-Ageel कीnअब्दुल्ला अल-Ageel काफी क्या व्याख्या नहीं करता nहोना चाहिए, लेकिन Nऔर kकि में मतभेद है Nकि " नमूने जहां पर औसत करना चाहते हैं की संख्या ", जबकि kनमूना मूल्यों की गिनती है। (हालांकि मुझे संदेह है कि क्या नमूनों की संख्या को कॉल करना है या नहींN सही है।)

और यहाँ हम नीचे उत्तर पर आते हैं। यह अनिवार्य रूप से एक ही पुरानी घातीय भारित चलती औसत है रूप से अन्य लोगों , इसलिए यदि आप एक विकल्प की तलाश में थे, तो यहीं रुक जाएं।

घातीय भारित चलती औसत

प्रारंभ में:

average = 0
counter = 0

प्रत्येक मूल्य के लिए:

counter += 1
average = average + (value - average) / min(counter, FACTOR)

अंतर min(counter, FACTOR)हिस्सा है। यह कहने जैसा ही है min(Flip's k, Muis's N)

FACTORएक निरंतरता है जो प्रभावित करती है कि नवीनतम प्रवृत्ति में औसत "कैच अप" कितनी जल्दी होता है। तेजी से संख्या को छोटा करें। ( 1अब यह एक औसत नहीं है और बस नवीनतम मूल्य बन जाता है।)

इस उत्तर के लिए रनिंग काउंटर की आवश्यकता होती है counter। यदि समस्याग्रस्त है, तो min(counter, FACTOR)बस के साथ प्रतिस्थापित किया जा सकता हैFACTOR इसे मुइस के उत्तर में बदलकर, । ऐसा करने के साथ समस्या यह है कि जो कुछ भी averageआरंभ किया जाता है उससे चलती औसत प्रभावित होती है । अगर इसे इनिशियलाइज़ किया गया0 , तो उस शून्य को औसत से बाहर का रास्ता तय करने में लंबा समय लग सकता है।

यह कैसे देख समाप्त होता है

घातीय चलती औसत


3
अच्छी तरह से समझाया गया। मुझे आपके ग्राफ में एक सादा औसत याद आता है, क्योंकि ओपी ने जो पूछा है।
xmedeko

शायद मुझे कुछ याद आ रहा है, लेकिन क्या आपने संयोग से, मतलब है max(counter, FACTOR)min(counter, FACTOR)हमेशा FACTOR लौटाएगा, है ना?
वेबवैंडर

1
मेरा मानना ​​है min(counter, FACTOR)कि वार्म अप अवधि के लिए खाते की बात है । इसके बिना, यदि आपका FACTOR (या N, या वांछित नमूना गणना) 1000 है, तो आपको सटीक परिणाम प्राप्त करने से पहले कम से कम 1000 नमूनों की आवश्यकता होगी, क्योंकि इससे पहले के सभी अपडेट मान लेंगे कि आपके पास 1000 नमूने हैं, जब आप केवल हो सकते हैं 20. है
राहटर

कारक तक पहुंचने के बाद गिनती रोकना अच्छा होगा, शायद यह उस तरह से तेज होगा।
inf3rno

8

Flip का उत्तर कम्प्यूटेशनल रूप से म्यूइस वन की तुलना में अधिक सुसंगत है।

दोहरे नंबर प्रारूप का उपयोग करके, आप म्यूइस दृष्टिकोण में राउंडऑफ़ समस्या देख सकते हैं:

म्यूइस दृष्टिकोण

जब आप विभाजित करते हैं और घटाते हैं, तो एक राउंडऑफ़ पिछले संग्रहित मूल्य में प्रकट होती है, इसे बदल देती है।

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

फ्लिप दृष्टिकोण

जब आप बड़े मूल्यों का अर्थ शून्य करते हैं, तो वे परिवर्तन उल्लेखनीय होते हैं।

मैं आपको एक स्प्रेडशीट प्रोग्राम का उपयोग करके परिणाम दिखाता हूं:

सबसे पहले, प्राप्त परिणाम: परिणाम

A और B कॉलम क्रमशः n और X_n मान हैं।

C कॉलम फ्लिप दृष्टिकोण है, और D एक म्यूइस दृष्टिकोण है, जो माध्य में संग्रहीत है। ई कॉलम संगणना में प्रयुक्त मध्यम मूल्य के साथ मेल खाता है।

समान मानों का माध्य दिखाने वाला ग्राफ अगला है:

ग्राफ़

जैसा कि आप देख सकते हैं, दोनों दृष्टिकोणों के बीच बड़ा अंतर है।


2
वास्तव में एक उत्तर नहीं है, लेकिन उपयोगी जानकारी है। यह बेहतर होगा यदि आप अपने ग्राफ में 3 लाइन जोड़ते हैं, एन पिछले मानों पर सही औसत के लिए , इसलिए हम देख सकते हैं कि दोनों दृष्टिकोणों में से कौन सा दृष्टिकोण निकटतम है।
jpaugh

2
@jpaugh: बी कॉलम -1.00E + 15 और 1.00E + 15 के बीच बारी-बारी से होता है, इसलिए जब N सम होता है, तो वास्तविक अर्थ 0. होना चाहिए। ग्राफ़ का शीर्षक "यहां तक ​​कि आंशिक साधन" है। इसका मतलब यह है कि आप जिस 3 लाइन के बारे में पूछते हैं वह बस एफ (x) = 0 है। ग्राफ दिखाता है कि दोनों दृष्टिकोण त्रुटियों को पेश करते हैं जो ऊपर और ऊपर जाते रहते हैं।
desowin

यह सही है, ग्राफ़ दोनों दृष्टिकोणों का उपयोग करके गणना में शामिल बड़ी संख्याओं का उपयोग करके त्रुटि को ठीक से दिखाता है।
जोस मैनुअल रामोस

आपके ग्राफ की किंवदंती में गलत रंग हैं: म्यूइस ऑरेंज है, फ्लिप ब्लू है।
xmedeko

6

तुलना के लिए जावास्क्रिप्ट का उपयोग करने वाला एक उदाहरण:

https://jsfiddle.net/drzaus/Lxsa4rpz/

function calcNormalAvg(list) {
    // sum(list) / len(list)
    return list.reduce(function(a, b) { return a + b; }) / list.length;
}
function calcRunningAvg(previousAverage, currentNumber, index) {
    // [ avg' * (n-1) + x ] / n
    return ( previousAverage * (index - 1) + currentNumber ) / index;
}


1

Java8 में:

LongSummaryStatistics movingAverage = new LongSummaryStatistics();
movingAverage.accept(new data);
...
average = movingAverage.getAverage();

आपके पास भी है IntSummaryStatistics, DoubleSummaryStatistics...


2
ओपी एक एल्गोरिथ्म के लिए पूछ रहा है, न कि पॉइंटर के लिए कि यह जावा में कैसे गणना की जाए।
olq_plo

0

उपरोक्त उत्तरों के आधार पर एक साफ पायथन समाधान:

class RunningAverage():
    def __init__(self):
        self.average = 0
        self.n = 0
        
    def __call__(self, new_value):
        self.n += 1
        self.average = (self.average * (self.n-1) + new_value) / self.n 
        
    def __float__(self):
        return self.average
    
    def __repr__(self):
        return "average: " + str(self.average)

उपयोग:

x = RunningAverage()
x(0)
x(2)
x(4)
print(x)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.