हाइपरलॉग एल्गोरिथ्म कैसे काम करता है?


172

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

यह मेरे लिए विशेष रूप से दिलचस्प था क्योंकि यह मुझे मेरे MySQL दिनों में वापस लाया जब मैंने देखा कि "कार्डिनैलिटी" मूल्य (जो मैंने हाल ही में तब तक मान लिया था जब तक यह अनुमान नहीं लगाया गया था)।

तो मुझे पता है कि ( एन ) में एक एल्गोरिथ्म कैसे लिखना है, जो गणना करेगा कि एक सरणी में कितने अद्वितीय आइटम हैं। मैंने इसे जावास्क्रिप्ट में लिखा है:

function countUniqueAlgo1(arr) {
    var Table = {};
    var numUnique = 0;
    var numDataPoints = arr.length;
    for (var j = 0; j < numDataPoints; j++) {
        var val = arr[j];
        if (Table[val] != null) {
            continue;
        }
        Table[val] = 1;
        numUnique++;
    }
    return numUnique;
}

लेकिन समस्या यह है कि मेरा एल्गोरिथ्म, जबकि O ( n ), बहुत सारी मेमोरी (मानों को संग्रहीत करना Table) का उपयोग करता है ।

मैं इस पत्र को O ( n ) समय की सूची में डुप्लिकेट की गणना करने और न्यूनतम मेमोरी का उपयोग करने के बारे में पढ़ रहा हूं ।

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

मैंने पेपर पढ़ा है, लेकिन मैं इसे समझ नहीं पा रहा हूं। क्या कोई अधिक लेपर्सन स्पष्टीकरण दे सकता है? मुझे पता है कि क्या हैश हैं, लेकिन मुझे समझ में नहीं आता है कि इस हाइपरलॉग एल्गोरिथ्म में उनका उपयोग कैसे किया जाता है।


4
यह पत्र ( research.google.com/pubs/pub40671.html ) भी HyperLogLog एल्गोरिथ्म और कुछ सुधारों को संक्षेप में प्रस्तुत करता है। मुझे लगता है कि मूल पेपर की तुलना में इसे समझना आसान है।
zhanxw

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

जवाबों:


153

इस एल्गोरिथ्म के पीछे मुख्य चाल यह है कि यदि आप यादृच्छिक पूर्णांकों की एक धारा का अवलोकन करते हैं, तो एक पूर्णांक देखें जो द्विआधारी प्रतिनिधित्व कुछ ज्ञात उपसर्ग के साथ शुरू होता है, एक उच्च संभावना है कि धारा की कार्डिनैलिटी 2 ^ है (उपसर्ग का आकार) ।

यही है, पूर्णांकों की एक यादृच्छिक धारा में, ~ 50% संख्या (बाइनरी में) "1" से शुरू होती है, 25% "01" से शुरू होती है, 12,5% "001" से शुरू होती है। इसका मतलब यह है कि यदि आप एक यादृच्छिक स्ट्रीम का निरीक्षण करते हैं और "001" देखते हैं, तो एक उच्च संभावना है कि इस स्ट्रीम में 8 की कार्डिनैलिटी है।

(उपसर्ग "00..1" का कोई विशेष अर्थ नहीं है। यह सिर्फ इसलिए है क्योंकि अधिकांश प्रोसेसर में एक द्विआधारी संख्या में सबसे महत्वपूर्ण बिट खोजना आसान है)

बेशक, यदि आप केवल एक पूर्णांक का निरीक्षण करते हैं, तो यह मान गलत है। यही कारण है कि एल्गोरिथ्म "एम" स्वतंत्र सबस्ट्रीम में स्ट्रीम को विभाजित करता है और प्रत्येक सब्स्ट्रीम के पहले "00 ... 1" उपसर्ग की अधिकतम लंबाई रखता है। फिर, प्रत्येक सबस्ट्रीम का माध्य मान लेकर अंतिम मान का अनुमान लगाता है।

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


"अधिक संभावना है कि इस स्ट्रीम में 8 की कार्डिनैलिटी है" क्या आप बता सकते हैं कि 000 का मतलब 2 के परीक्षण की अपेक्षित संख्या 2 ^ 3 है। मैंने यह मानने की कोशिश की कि हम तीन ज़ीरो के साथ कम से कम एक रन की कोशिश करें और 4 शून्य के साथ कोई रन न लें ...
yura

5
जब तक मैंने इसे नहीं पढ़ा, तब तक पेपर को बहुत समझ नहीं पाया। अब समझ में आता है।
जोसिया

5
@ आपको पता है कि यह एक बहुत पुरानी टिप्पणी है, लेकिन यह अन्य लोगों के लिए उपयोगी हो सकती है। उन्होंने कहा कि "पूर्णांक की एक यादृच्छिक धारा में, (...) 12,5%" 001 "से शुरू होता है।" संभावित कार्डिनैलिटी 8 है क्योंकि 12,5% पूरे स्ट्रीम के आठवें हिस्से का प्रतिनिधित्व करता है।
Braunmagrin

111

एक हाइपरलॉग एक संभावना डेटा संरचना है । यह एक सूची में विभिन्न तत्वों की संख्या को गिनता है। लेकिन इसे करने के एक सीधे तरीके की तुलना में (एक सेट होने और सेट में तत्वों को जोड़ना) यह एक अनुमानित तरीके से करता है।

यह देखने से पहले कि हाइपरलॉग एल्गोरिथ्म कैसे करता है, किसी को यह समझना होगा कि आपको इसकी आवश्यकता क्यों है। सीधे तरीके से समस्या यह है कि यह O(distinct elements)अंतरिक्ष की खपत करता है। सिर्फ अलग-अलग तत्वों के बजाय यहां एक बड़ा O अंकन क्यों है? ऐसा इसलिए है क्योंकि तत्व विभिन्न आकारों के हो सकते हैं। एक तत्व 1दूसरा तत्व हो सकता है "is this big string"। इसलिए यदि आपके पास एक विशाल सूची (या तत्वों की एक विशाल धारा) है तो यह बहुत अधिक स्मृति लेगा।


संभाव्य गणना

कई अनूठे तत्वों की एक उचित अनुमान कैसे प्राप्त कर सकते हैं? मान लें कि आपके पास लंबाई की एक स्ट्रिंग है mजो {0, 1}समान संभावना के साथ होती है। क्या संभावना है कि यह 0 के साथ शुरू होगा, 2 शून्य के साथ, के शून्य के साथ? यह है 1/2, 1/4और 1/2^k। इसका मतलब है कि यदि आपने kशून्य के साथ एक स्ट्रिंग का सामना किया है , तो आपने लगभग 2^kतत्वों के माध्यम से देखा है। तो यह एक अच्छा शुरुआती बिंदु है। उन तत्वों की एक सूची है, जो समान रूप से वितरित किए जाते हैं 0और 2^k - 1आप बाइनरी प्रतिनिधित्व में शून्य के सबसे बड़े उपसर्ग की अधिकतम संख्या की गणना कर सकते हैं और यह आपको एक उचित अनुमान देगा।

समस्या यह है कि 0टी से समान रूप से वितरित संख्या होने की धारणा 2^k-1को प्राप्त करना बहुत कठिन है (हमारे द्वारा सामना किया गया डेटा ज्यादातर संख्या नहीं है, लगभग कभी समान रूप से वितरित नहीं किया जा सकता है, और किसी भी मूल्य के बीच हो सकता है। लेकिन एक अच्छे हैशिंग फ़ंक्शन का उपयोग करके आप यह मान सकते हैं। आउटपुट बिट्स समान रूप से वितरित किए जाएंगे और अधिकांश हैशिंग फ़ंक्शन के बीच आउटपुट होते हैं 0और 2^k - 1( SHA1 आपको बीच 0- बीच में मान देते हैं 2^160)। इसलिए हमने अब तक जो हासिल किया है, वह यह है कि हम kकेवल स्टोर करके बिट्स की अधिकतम कार्डिनैलिटी के साथ अद्वितीय तत्वों की संख्या का अनुमान लगा सकते हैं। आकार log(k)बिट्स की एक संख्या । नकारात्मक पक्ष यह है कि हमारे अनुमान में एक विशाल विचरण है। एक अच्छी बात जो हमने लगभग बनाई है1984 की संभाव्य मतगणना कागज़ (यह अनुमान के साथ थोड़ी सी होशियार है, लेकिन फिर भी हम करीब हैं)।

LogLog

आगे बढ़ने से पहले, हमें यह समझना होगा कि हमारा पहला अनुमान इतना महान क्यों नहीं है। इसके पीछे कारण यह है कि उच्च आवृत्ति 0-उपसर्ग तत्व की एक यादृच्छिक घटना सब कुछ खराब कर सकती है। इसे सुधारने का एक तरीका कई हैश फ़ंक्शंस का उपयोग करना है, प्रत्येक हैश फ़ंक्शंस के लिए अधिकतम गणना करना और अंत में उन्हें औसत करना है। यह एक उत्कृष्ट विचार है, जो अनुमान में सुधार करेगा, लेकिन लॉगलॉग पेपर ने थोड़ा अलग दृष्टिकोण का उपयोग किया (शायद इसलिए हैशिंग बहुत महंगा है)।

उन्होंने एक हैश का उपयोग किया लेकिन इसे दो भागों में विभाजित किया। एक को बाल्टी कहा जाता है (बाल्टी की कुल संख्या 2^x) और दूसरा - मूल रूप से हमारे हैश के समान है। मेरे लिए यह कठिन था कि मैं क्या करूं, इसलिए मैं एक उदाहरण दूंगा। मान लें कि आपके पास दो तत्व और आपका हैश फ़ंक्शन है जो मानों 0को 2^10निर्मित 2 मान देता है: 344और 387। आपने 16 बाल्टियाँ रखने का फैसला किया। मतलब आपके पास है:

0101 011000  bucket 5 will store 1
0110 000011  bucket 6 will store 4

अधिक बाल्टियाँ होने से आप विचरण को कम कर देते हैं (आप थोड़ी अधिक जगह का उपयोग करते हैं, लेकिन यह अभी भी छोटा है)। गणित कौशल का उपयोग करके वे त्रुटि (जो है 1.3/sqrt(number of buckets)) को निर्धारित करने में सक्षम थे ।

HyperLogLog

HyperLogLog किसी भी नए विचारों को पेश नहीं करता है, लेकिन पिछले अनुमान को बेहतर बनाने के लिए ज्यादातर गणित का उपयोग करता है। शोधकर्ताओं ने पाया है कि यदि आप बाल्टी से सबसे बड़ी संख्या का 30% निकालते हैं तो आप अनुमान में काफी सुधार करते हैं। उन्होंने औसत संख्या के लिए एक और एल्गोरिथ्म का भी उपयोग किया। पेपर गणित-भारी है।


और मैं हाल ही में एक पेपर के साथ समाप्त करना चाहता हूं, जो हाइपरलॉग एल्गोरिथ्म का एक उन्नत संस्करण दिखाता है (अब तक मेरे पास इसे पूरी तरह से समझने का समय नहीं था, लेकिन शायद बाद में मैं इस उत्तर को सुधारूंगा )।


2
मैं सैद्धांतिक रूप k zeroesसे मान रहा हूं कि यह कोई खास बात नहीं है। आप इसके बजाय देख सकते हैं k onesऔर तर्क समान होगा या यहां तक ​​कि k lengthस्ट्रिंग की तलाश करेंगे {0,1}लेकिन एक ऐसी स्ट्रिंग लें और उसके साथ रहें? क्योंकि उन सभी को ऐसे बाइनरी स्ट्रिंग्स के मामले में 1/2 ^ k की समान संभावना है?
user881300

3
हाइपरलॉगलॉग सबसे बड़ी संख्या का 30% नहीं हटाता है। यह LogLog पेपर में वर्णित सुपरलॉग एल्गोरिथ्म का विचार है। हाइपरलॉगलॉग एल्गोरिथ्म का मुख्य विचार सुपरमॉगलॉग और लॉगलॉग द्वारा उपयोग किए जाने वाले ज्यामितीय माध्य के बजाय हार्मोनिक माध्य का उपयोग करके टॉस की शक्ति को औसत करना है।
ओटमार

21

अंतर्ज्ञान अगर आपका इनपुट यादृच्छिक संख्या (जैसे हैशेड मान) का एक बड़ा सेट है, तो उन्हें एक सीमा पर समान रूप से वितरित किया जाना चाहिए। मान लीजिए कि अधिकतम 1024 तक मान का प्रतिनिधित्व करने के लिए सीमा 10 बिट तक है। फिर न्यूनतम मान का अवलोकन किया। मान लीजिए कि यह 10. है। तब कार्डिनैलिटी लगभग 100 (10 × 100 is 1024) होने का अनुमान होगा।

पाठ्यक्रम के असली तर्क के लिए पेपर पढ़ें।

नमूना कोड के साथ एक और अच्छा विवरण यहां पाया जा सकता है:
लानत कूल एल्गोरिथम: कार्डिनैलिटी अनुमान - निक का ब्लॉग


3
लानत शांत एल्गोरिदम ब्लॉग पोस्ट के लिंक के लिए upvoted कि वास्तव में मुझे एल्गोरिथ्म को समझने में मदद मिली।
इगोर सेरेब्यानी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.