HyperLogLog olasılıklı bir veri yapısıdır . Listedeki farklı öğelerin sayısını sayar. Ancak bunu yapmanın basit bir yoluna kıyasla (bir kümeye sahip olmak ve kümeye öğeler eklemek) bunu yaklaşık olarak yapar.
HyperLogLog algoritmasının bunu nasıl yaptığını görmeden önce, neden ona ihtiyacınız olduğunu anlamak gerekir. Basit bir şekilde sorun O(distinct elements)
, yer tüketmesidir . Neden burada sadece farklı unsurlar yerine büyük bir O notasyonu var? Bunun nedeni elemanların farklı boyutlarda olabilmesidir. Bir öğe 1
başka bir öğe olabilir "is this big string"
. Bu nedenle, büyük bir listeniz (veya büyük bir öğe akışı) varsa, çok fazla bellek alır.
Olasılıksal Sayım
Bir dizi benzersiz element hakkında makul bir tahmin nasıl elde edilebilir? Eşit olasılıkla m
oluşan bir uzunluk dizeniz olduğunu varsayın {0, 1}
. 0 ile, 2 sıfır ile, k sıfırlarla başlama olasılığı nedir? Öyle 1/2
, 1/4
ve 1/2^k
. Bu, k
sıfırlarla bir dizeyle karşılaşırsanız , yaklaşık olarak 2^k
öğelere baktığınız anlamına gelir . Yani bu iyi bir başlangıç noktası. 0
Ve arasında eşit olarak dağıtılan öğelerin bir listesine sahip olmak2^k - 1
ikili sunumdaki en büyük sıfır önekinin maksimum sayısını sayabilirsiniz ve bu size makul bir tahmin verecektir.
Sorun dan eşit olarak dağıtılmış sayılarına sahip olan varsayım olduğunu 0
t 2^k-1
karşılaştığımız veri çoğunlukla neredeyse eşit olarak dağıtılmış asla değil sayılardır (elde etmek çok zor olduğunu ve herhangi değerler arasında olabilir. Ama kullanarak iyi bir karma işlev size varsayabiliriz çıkış bitleri eşit olarak dağıtılır ve çoğu hash fonksiyonu 0
ve 2^k - 1
( SHA1 size 0
ve arasında değerler verir) çıkışlarına sahiptir 2^160
. Şimdiye kadar elde ettiğimiz şey, k
sadece maksimum depolama ile benzersiz elemanların sayısını sadece maksimum depolama ile tahmin edebilmemizdir. boyut log(k)
bitlerinin bir kısmı dezavantajı, tahminimizde büyük bir varyansımızın olması Neredeyse yarattığımız harika bir şey1984'ün olasılıksal sayım kağıdı (tahminle biraz daha akıllıdır, ancak yine de yakınız).
loglog
Daha ileriye gitmeden önce, ilk tahminimizin neden bu kadar büyük olmadığını anlamalıyız. Bunun nedeni, yüksek frekanslı 0-önek elemanının rastgele bir oluşumunun her şeyi bozabilmesidir. Bunu geliştirmenin bir yolu, birçok karma işlevini kullanmak, karma işlevlerinin her biri için maks. Saymak ve sonunda bunları ortalamaktır. Bu, tahmini artıracak mükemmel bir fikir, ancak LogLog kağıdı biraz farklı bir yaklaşım kullandı (muhtemelen hash biraz pahalı olduğu için).
Bir karma kullandılar ama iki parçaya ayırdılar. Birine kova denir (toplam kova sayısı 2^x
) ve diğeri - temel olarak karmamızla aynıdır. Olanları elde etmek benim için zor oldu, bu yüzden bir örnek vereceğim. İki öğeniz olduğunu 0
ve 2^10
üretilen 2 değere değerler veren sağlama işlevinizin olduğunu varsayalım : 344
ve 387
. 16 kova almaya karar verdin. Yani:
0101 011000 bucket 5 will store 1
0110 000011 bucket 6 will store 4
Daha fazla kova ile varyansı azaltırsınız (biraz daha fazla alan kullanırsınız, ancak yine de küçüktür). Matematik becerilerini kullanarak hatayı (yani 1.3/sqrt(number of buckets)
) ölçmeyi başardılar .
HyperLogLog
HyperLogLog herhangi bir yeni fikir sunmaz, ancak önceki tahmini iyileştirmek için çoğunlukla çok fazla matematik kullanır. Araştırmacılar, en büyük sayıların% 30'unu kovalardan kaldırırsanız, tahmini önemli ölçüde iyileştirdiğinizi bulmuşlardır. Ayrıca sayıların ortalaması için başka bir algoritma kullandılar. Kağıt matematik ağırlıklı.
Ve hyperLogLog algoritmasının geliştirilmiş bir versiyonunu gösteren yeni bir kağıtla bitirmek istiyorum (şimdiye kadar tam olarak anlayacak zamanım yoktu, ama belki de daha sonra bu cevabı geliştireceğim).