2009-05-21 6 views
16

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

ये सभी फ़्लोटिंग पॉइंट नंबर हैं।

यह डेटाबेस से नहीं पढ़ा जाता है, यह कई स्रोतों से एकत्रित एक CSV फ़ाइल है। इसे सटीक होना चाहिए क्योंकि इसे दूसरे के हिस्सों (उदाहरण के लिए; 0.2 9 3482888929) के रूप में संग्रहीत किया जाता है और रोलिंग औसत .2 और .3

के बीच अंतर हो सकता है यह # का प्रतिनिधित्व करता है कि उपयोगकर्ताओं ने कितना समय लिया कुछ रूपों के कार्यों का जवाब देने के लिए। उदाहरण के लिए जब एक संदेशबॉक्स दिखाते हैं, तो उन्हें ठीक या रद्द करने के लिए कितना समय लगता है। डेटा मुझे सेकंड के रूप में संग्रहीत किया गया था। एक सेकंड के भाग; उदाहरण के लिए 1.2347 सेकंड। इसे मिलीसेकंड में परिवर्तित करना और मैं int, लंबे, इत्यादि को बहती हूं .. बल्कि जल्दी से। यहां तक ​​कि अगर मैं इसे परिवर्तित नहीं करता हूं, तब भी मैं इसे जल्दी से बहता हूं। मुझे लगता है कि नीचे दिया गया एक उत्तर सही है, शायद मुझे 100% सटीक होना जरूरी नहीं है, बस एक सीपीसिफिक स्टडीडेव के अंदर एक निश्चित सीमा के भीतर देखें और मैं काफी करीब रहूंगा।

+0

एक डेटाबेस में संग्रहीत संख्या के इस सेट है –

+2

सही कितना सही है – flq

+0

आप स्पष्ट कर सकते हैं आप की आवश्यकता परिशुद्धता का स्तर क्या –

उत्तर

18

आप कर सकते हैं से अपने गणना कर सकता है औसत ("mean") प्राप्त करने के लिए अपने सेट से यादृच्छिक रूप से नमूना ("population")। शुद्धता निर्धारित की जाएगी कि आपके नमूने कितने भिन्न होते हैं (जैसा कि "standard deviation" या भिन्नता द्वारा निर्धारित किया गया है)।

लाभ यह है कि आपके पास अरबों अवलोकन हैं, और आपको केवल अपनी पसंद के "सभ्य सटीकता या" confidence range "प्राप्त करने के लिए उनमें से एक अंश का नमूना देना होगा। यदि शर्तें सही हैं, तो यह आपके द्वारा किए जा रहे काम की मात्रा को कम कर देता है।

यहां सी # के लिए numerical library है जिसमें एक यादृच्छिक क्रम जनरेटर शामिल है। बस संख्याओं का एक यादृच्छिक अनुक्रम बनाएं जो आपके तत्वों की सरणी में सूचकांक (1 से x, आपके सरणी में तत्वों की संख्या) का संदर्भ देता है। मान प्राप्त करने के लिए अस्वीकृति, और फिर अपने माध्य और मानक विचलन की गणना करें।

आप अपने डेटा के वितरण का परीक्षण Chi-Squared Fit परीक्षण या K-S परीक्षण है, जो आपको कई स्प्रेडशीट और सांख्यिकीय संकुल में मिलेगा उपयोग करने पर विचार करना चाहते हैं (उदाहरण के लिए, R)। इससे यह पुष्टि करने में मदद मिलेगी कि यह दृष्टिकोण प्रयोग योग्य है या नहीं।

+0

मान लीजिए कि वह किस आत्मविश्वास सीमा की आवश्यकता है, यह निर्णय ले सकता है, यह अच्छी सलाह है। +1 –

+1

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

+0

+1, राजनीतिक परावर्तक केवल जनसंख्या का 1/100,000 वां साक्षात्कार करते हैं और फिर भी आमतौर पर इसे सही पाते हैं! –

13

इंटीग्रर्स या फ्लोट्स?

यदि वे पूर्णांक हैं, तो आपको संख्याओं को पढ़ने और रिकॉर्डिंग के प्रत्येक आवृत्ति को रिकॉर्ड करके आवृत्ति वितरण जमा करने की आवश्यकता है। यह आसानी से औसत किया जा सकता है।

फ़्लोटिंग पॉइंट के लिए, यह एक समस्या है। फ्लोट्स और वास्तविक वितरण की समग्र सीमा को देखते हुए, आपको एक बिन-आकार का काम करना होगा जो सभी संख्याओं को संरक्षित किए बिना सटीकता को सुरक्षित रखता है।


संपादित

सबसे पहले, आप एक मतलब है और एक मानक विचलन प्राप्त करने के लिए आपके डेटा का नमूना की जरूरत है। कुछ हज़ार अंक काफी अच्छे होना चाहिए।

फिर, आपको एक सम्मानजनक सीमा निर्धारित करने की आवश्यकता है। लोग मतलब के आसपास ± 6σ (मानक विचलन) जैसी चीज़ों को चुनते हैं। आप इस सीमा को उतनी बाल्टी में विभाजित करेंगे जितना आप खड़े हो सकते हैं।

असल में, बाल्टी की संख्या आपके औसत में महत्वपूर्ण अंकों की संख्या निर्धारित करती है। तो, परिशुद्धता के 4 या 5 अंक प्राप्त करने के लिए 10,000 या 100,000 बाल्टी चुनें। चूंकि यह एक माप है, बाधाएं अच्छी हैं कि आपके माप में केवल दो या तीन अंक हैं।


संपादित

क्या आपको पता चल जाएगा कि आपके प्रारंभिक नमूने के मतलब बहुत किसी अन्य नमूने के मतलब के करीब है। और किसी भी नमूना मतलब आबादी के मतलब के करीब है। आप ध्यान दें कि आपके साधनों में से अधिकांश (लेकिन सभी नहीं) एक दूसरे के 1 मानक विचलन के साथ हैं।

आपको यह पता होना चाहिए कि आपकी माप त्रुटियां और त्रुटियां आपके मानक विचलन से बड़ी हैं।

इसका मतलब है कि नमूना मतलब जनसंख्या के रूप में उपयोगी है।

+0

क्षमा करें, उसमें शामिल करना भूल गए। यह वैज्ञानिक डेटा है इसलिए यह तैरता है। –

0

संख्या की सीमा पर निर्भर करता है यह एक सरणी जहां अधोलिखित आपका नंबर है के लिए एक अच्छा विचार हो सकता है और मूल्य है कि संख्या की मात्रा है, तो आप इस

9

रोलिंग औसत किसी और चीज के रूप में सटीक नहीं होगा (गोल करने वाली त्रुटियों को छूट देना, मेरा मतलब है)? यह सभी विभाजन के कारण धीमा हो सकता है।

आप संख्याओं के बैच समूह कर सकते हैं और उन्हें दोबारा औसत कर सकते हैं। औसत 100 संख्याओं की तरह 100 बार, फिर परिणाम औसत। यह कम थकावट और अधिकतर अतिरिक्त होगा।

वास्तव में, यदि आप एक बार में 256 या 512 जोड़ते हैं तो आप 8 या 9 के परिणाम को थोड़ा-सा स्थानांतरित करने में सक्षम हो सकते हैं, (मुझे विश्वास है कि आप इसे फ्लोटिंग पॉइंट मंथिसा को बदलकर डबल में कर सकते हैं) - यह आपके कार्यक्रम को बहुत तेज़ी से बना देगा और इसे कोड की कुछ पंक्तियों में रिक्त रूप से लिखा जा सकता है (मंटिसा शिफ्ट के असुरक्षित संचालन की गणना नहीं)।

शायद 256 तक विभाजित करने से पहले ही इस अनुकूलन का उपयोग किया जाएगा? मुझे 255 बनाम 256 तक परीक्षण विभाजित करना पड़ सकता है और देख सकता है कि कुछ बड़े सुधार हुए हैं या नहीं। मैं अनुमान लगा रहा हूँ।

+1

बैचों में काम को विभाजित करने का एक अन्य लाभ: व्यक्तिगत बैच आसानी से बढ़ते प्रदर्शन के लिए अलग-अलग धागे में चला सकते हैं (मान लीजिए कि आप इस सार्थक बनाने के लिए पर्याप्त नए बैचों को बनाने में सक्षम हैं)। –

+0

सच है, लेकिन आपको यह सुनिश्चित करने के लिए सावधान रहना होगा कि प्रत्येक बैच एक ही आकार का हो या उसके आकार की गणना को बरकरार रखे, क्योंकि अंतिम विलय (विभिन्न "गणनाओं" के साथ) कुछ थोड़ा मुश्किल अनुपात गणित को शामिल करने जा रहा है। –

0

यदि संख्याएं int हैं, तो कुल में लंबे समय तक जमा करें। यदि संख्याएं लंबी हैं ... आप किस भाषा का उपयोग कर रहे हैं? जावा में आप कुल बिगइंटर में जमा कर सकते हैं, जो एक पूर्णांक है जो जितना बड़ा हो उतना बड़ा हो जाएगा। आप इस कार्यक्षमता को पुन: पेश करने के लिए हमेशा अपनी कक्षा लिख ​​सकते हैं। इसका अर्थ केवल "बड़ी संख्या" को पकड़ने के लिए पूर्णांक की सरणी बनाना है। जब आप दो-संख्या जोड़ते हैं, तो लो-ऑर्डर मान से शुरू करके लूप करें। यदि अतिरिक्त परिणाम उच्च ऑर्डर बिट सेट करता है, तो इस बिट को साफ़ करें और उसे अगले कॉलम पर ले जाएं।

एक और विकल्प एक समय में 1000 नंबरों का औसत, औसत कहना होगा। इन मध्यवर्ती परिणामों को पकड़ें, फिर जब आप उन्हें एक साथ औसत कर लेंगे।

5

आप डेटा को सेट कर सकते हैं, कह सकते हैं, 1000 नंबर, औसत औसत, और फिर औसत औसत।

+2

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

+1

ओपी का कहना है कि उसके पास कई गीगाबाइट हैं, इसलिए यदि उसके पास 4 जीबी है, तो उसके पास लगभग 1 बिलियन नमूना अंक हैं। 1000 का सेट, 1 मिलियन औसत छोड़ देता है। यह स्मृति में स्टोर करने के लिए काफी आसान है, और कहें, 1000 का एक और सेट। यह तेज़ और आसान है। 40 जीबी के साथ भी। औसतन 1 मिलियन औसत औसत के साथ, अंतिम व्यक्ति को सही ढंग से भारित नहीं किया जा रहा है, यह काफी अपरिहार्य लगता है, या बस इसे एक साथ छोड़ दें। लेकिन यकीन है कि अगर वे चाहते थे तो कोई इसे वजन दे सकता है। – tom10

0

फ़्लोटिंग पॉइंट नंबरों की संख्या क्यों बहती है? ऐसा होने के लिए, आपको अधिकतम फ्लोट मान के पास मूल्य होना चाहिए, जो अजीब लगता है।

यदि आप पूर्णांक से निपट रहे थे तो मैं बिगइंटर का उपयोग करने का सुझाव दूंगा, या सेट को एकाधिक सबसेट में तोड़ने का सुझाव दूंगा, फिर से सबसेट्स का औसत, औसत औसत औसत।

यदि आप फ्लोट से निपट रहे हैं, तो यह थोड़ा अजीब हो जाता है। एक रोलिंग औसत बहुत गलत हो सकता है। मैं एक रोलिंग औसत का उपयोग करने का सुझाव देता हूं जिसे केवल तब अपडेट किया जाता है जब आप ओवरफ़्लो अपवाद या सेट के अंत को दबाते हैं। तो सेट को गैर-बहने वाले सेट में प्रभावी ढंग से विभाजित करना। मुझ से

0

दो विचारों: -, इस बहुत धीमी गति से हो सकता है, हालांकि

  • संख्या तैरता रहे हैं और आप जानते हैं कि कुल राशि

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

    यहाँ एक ही रास्ता स्यूडोकोड में यह करना है:

     
    average=first 
    count=1 
    while more: 
        count+=1 
        diff=next-average 
        average+=diff/count 
    return average 
    
    +1

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

    7

    आप 32-बिट और 64-बिट संख्या के मतलब है। लेकिन क्यों न सिर्फ एक उचित तर्कसंगत बिग न्यू पुस्तकालय का उपयोग करें? यदि आपके पास इतना डेटा है और आप एक सटीक मतलब चाहते हैं, तो बस इसे कोड करें।

    class RationalBignum { 
        public Bignum Numerator { get; set; } 
        public Bignum Denominator { get; set; } 
    } 
    
    class BigMeanr { 
        public static int Main(string[] argv) { 
         var sum = new RationalBignum(0); 
         var n = new Bignum(0); 
         using (var s = new FileStream(argv[0])) { 
          using (var r = new BinaryReader(s)) { 
           try { 
            while (true) { 
             var flt = r.ReadSingle(); 
             rat = new RationalBignum(flt); 
             sum += rat; 
             n++; 
            } 
           } 
           catch (EndOfStreamException) { 
            break; 
           } 
          } 
         } 
         Console.WriteLine("The mean is: {0}", sum/n); 
        } 
    } 
    

    बस, याद अधिक सांख्यिक प्रकार लोगों को अपने संकलक आप प्रदान करता है की तुलना में वहाँ नहीं है।

    3

    चाल यह है कि आप एक अतिप्रवाह के बारे में चिंतित हैं। उस स्थिति में, यह निष्पादन के आदेश के लिए नीचे आता है। बुनियादी सूत्र इस तरह है:

    को देखते हुए:

     
    A = current avg 
    C = count of items 
    V = next value in the sequence 
    
    अगले औसत (ए) है:

     
         (C * A) + V 
    A1 = ——————————— 
         C + 1 
    

    खतरा है कि आप चिंतित हैं कि अनुक्रम evaulating के पाठ्यक्रम पर है, जबकि A अपेक्षाकृत प्रबंधनीय रहना चाहिए सी बहुत बड़ा हो जाएगा।
    आखिरकार सी * ए पूर्णांक या डबल प्रकारों को बह जाएगा।

     
    A1 = C/(C+1) * A/(C+1) + V/(C+1) 
    

    इस तरह, हम गुणा कभी नहीं सी * एक और केवल छोटी संख्याओं के साथ सौदा:

    एक बात हम कोशिश कर सकते हैं इसे इस तरह फिर से लिखने के लिए, एक अतिप्रवाह की संभावना को कम किया जा सके। लेकिन चिंता अब विभाजन संचालन का परिणाम है। यदि सी बहुत बड़ा है, तो C/C+1 (उदाहरण के लिए) सामान्य फ़्लोटिंग पॉइंट प्रस्तुतियों को बाधित होने पर सार्थक नहीं हो सकता है। सबसे अच्छा मैं सुझाव दे सकता हूं कि यहां सी के लिए सबसे बड़ा प्रकार संभव है।

    +1

    जबकि मुझे चल रहे औसत विचार पसंद हैं, मुझे यह अपरिपूर्णता पसंद नहीं है, मुझे लगता है कि 100 आइटम कहने के लिए योग एकत्र करना सबसे अच्छा होगा, फिर उन्हें औसत –

    +0

    अच्छा बिंदु में जोड़ें। विभाजन और विजय दृष्टिकोण यहां कहीं बेहतर है, और मैंने सुझावों में से एक को उखाड़ फेंक दिया। न केवल सी/सी + 1 परिशुद्धता समस्या से बचता है, बल्कि प्रदर्शन को बेहतर बनाने के लिए इसे समानांतर में आसानी से किया जा सकता है। –

    +0

    मेरा गणित यहां बंद हो जाता है - आपके पास सी है, जो आप कहते हैं "अनंत की ओर जाएं" या कम से कम, वास्तव में एक बड़ी संख्या, फिर: सी/(सी + 1) 1/(सी + 1) की तरफ जाता है। 0. वी/(सी + 1) की ओर जाता है 0. सभी सब में की ओर जाता है: ए 1 = 1 * 0 + 0 तो शीघ्र ही डाल A1 0 की ओर जाता है - थोड़ा दूर लगता है। – kastermester

    4

    यह एक क्लासिक विभाजन-और-विजय प्रकार की समस्या है।

    मुद्दा यह है कि सेट के पहले भाग के औसत के रूप में संख्याओं के एक बड़े सेट का औसत है, जो सेट के दूसरे भाग के औसत के औसत से औसत है।

    दूसरे शब्दों में:

    AVG(A[1..N]) == AVG(AVG(A[1..N/2]), AVG(A[N/2..N])) 
    

    यहाँ एक सरल, सी #, पुनरावर्ती समाधान है। यह मेरे परीक्षण पास कर दिया, और पूरी तरह से सही होना चाहिए।

    public struct SubAverage 
    { 
        public float Average; 
        public int Count; 
    }; 
    
    static SubAverage AverageMegaList(List<float> aList) 
    { 
        if (aList.Count <= 500) // Brute-force average 500 numbers or less. 
        { 
         SubAverage avg; 
         avg.Average = 0; 
         avg.Count = aList.Count; 
         foreach(float f in aList) 
         { 
          avg.Average += f; 
         } 
         avg.Average /= avg.Count; 
         return avg; 
        } 
    
        // For more than 500 numbers, break the list into two sub-lists. 
        SubAverage subAvg_A = AverageMegaList(aList.GetRange(0, aList.Count/2)); 
        SubAverage subAvg_B = AverageMegaList(aList.GetRange(aList.Count/2, aList.Count-aList.Count/2)); 
    
        SubAverage finalAnswer; 
        finalAnswer.Average = subAvg_A.Average * subAvg_A.Count/aList.Count + 
              subAvg_B.Average * subAvg_B.Count/aList.Count; 
        finalAnswer.Count = aList.Count; 
    
        Console.WriteLine("The average of {0} numbers is {1}", 
         finalAnswer.Count, finalAnswer.Average); 
        return finalAnswer; 
    } 
    
    +1

    यह एन% 2 = 1 के लिए थोड़ा गलत होगा, सही? – Hans

    +0

    इसके अलावा, प्रश्न "बहुत बड़ा" है, और आप एक स्टैक ओवरफ़्लो त्रुटि को दबाएंगे इस दृष्टिकोण के साथ। साइट को वास्तविक चीज़ के लिए नामित किया गया है। – Hans

    +0

    स्टैक मानते हुए 1000 कॉल की अधिकतम रिकर्सन गहराई हो सकती है, यह फ़ंक्शन 2^1000 * 500 तत्वों की सूची को संभालने में सक्षम होना चाहिए, जो लगभग 5E + 303 ... क्या आपके लिए इतना बड़ा है ?? – abelenky

    0

    औसत गणना करने से पहले संख्याओं (नीचे) को स्केल क्यों न करें?

    1

    देर से टिप्पणी के लिए खेद है, लेकिन क्या यह जोएल कोहौर्न द्वारा प्रदान किए गए सूत्र को गलत तरीके से लिखा गया है?

    मेरा मतलब है, बुनियादी सूत्र सही है:

    को देखते हुए:

    एक = वर्तमान औसत सी = आइटम की गणना वी अनुक्रम

    अगले औसत में = अगले मूल्य (A1) है:

    ए 1 = ((सी * ए) + V)/(सी + 1)

    लेकिन बजाय:

    ए 1 = सी/(सी + 1) * ए/(सी + 1) + V/(सी + 1)

    हम नहीं करना चाहिए था:

    ए 1 = सी/(सी + 1) * एक + V/(सी + 1)

    कि kastermester पद की व्याख्या करता है:

    "मेरा गणित बंद यहाँ टिक्स - आप सी, आप जो कहो "जाओ टी ओव्हर इन्फिनिटी "या कम से कम, वास्तव में एक बड़ी संख्या, फिर: सी/(सी + 1) की तरफ जाता है 1. ए/(सी + 1) 0 की तरफ जाता है। वी/(सी + 1) 0 की तरफ जाता है। सब कुछ : ए 1 = 1 * 0 + 0 तो जल्द ही ए 1 को 0 की ओर ले जाएं - थोड़ा सा लगता है। - kastermester "

    क्योंकि हम होता ए 1 = 1 * ए + 0, यानी, ए 1 ए, जो यह सही है की ओर जाता है

    मैं एक लंबे समय के लिए औसत की गणना के लिए इस तरह के विधि का उपयोग किया गया है और। ऊपर उल्लिखित परिशुद्धता समस्याओं मेरे लिए एक मुद्दा कभी नहीं किया गया है

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