HyperLogLogは、確率的データ構造です。リスト内の個別の要素の数をカウントします。しかし、それを行う単純な方法(セットを持ち、要素をセットに追加する)と比較すると、これはおおよその方法で行われます。
HyperLogLogアルゴリズムがこれをどのように行うかを調べる前に、なぜそれが必要なのかを理解する必要があります。簡単な方法の問題は、O(distinct elements)
スペースを消費することです。なぜ明確な要素だけでなく、大きなO表記があるのですか?これは、要素のサイズが異なる可能性があるためです。1つの要素を1
別の要素にすることができます"is this big string"
。したがって、巨大なリスト(または要素の巨大なストリーム)がある場合、大量のメモリが必要になります。
確率的カウント
いくつかの一意の要素の合理的な見積もりを取得するにはどうすればよいですか?等しい確率m
で構成される長さの文字列があるとします{0, 1}
。0、2つのゼロ、kのゼロで始まる確率はどれくらいですか?それは1/2
、1/4
と1/2^k
。これは、k
ゼロの文字列に遭遇した場合、ほぼ2^k
要素を調べたことを意味します。したがって、これは良い出発点です。要素のリストが均等に分散され0
てい2^k - 1
て、バイナリ表現でゼロの最大プレフィックスの最大数を数えることができ、これにより妥当な見積もりが得られます。
問題は、0
t からの数値が均等に分散しているという仮定は2^k-1
実現が難しいことです(遭遇したデータはほとんど数値ではなく、ほとんど均等に分散されておらず、任意の値の間にある可能性があります。しかし、適切なハッシュ関数を使用すると、出力ビットが均等に分散し、最もられるハッシュ関数の間に出力している0
と2^k - 1
(SHA1は、あなたが間の値を与える0
と2^160
)を。だから何我々はこれまでに達成したことは、我々は、最大カーディナリティとユニークな要素の数を推定することができるということであるk
だけで保存することにより、ビットサイズlog(k)
ビットの数が1つあります。欠点は、推定値に大きなばらつきがあることです。1984年の確率論的カウンティングペーパー(見積もりの方が少し賢明ですが、それでも私たちは近いです)。
LogLog
先に進む前に、最初の見積もりがそれほど大きくない理由を理解する必要があります。その背後にある理由は、高周波の0プレフィックス要素が1回ランダムに発生すると、すべてが損なわれる可能性があるためです。それを改善する1つの方法は、多くのハッシュ関数を使用し、各ハッシュ関数の最大数を数え、最終的にそれらを平均することです。これは優れたアイデアであり、見積もりは改善されますが、LogLogペーパーでは少し異なるアプローチが使用されました(おそらくハッシュが一種の高価なため)。
彼らは1つのハッシュを使用しましたが、2つの部分に分割しました。1つはバケット(バケットの総数は2^x
)と呼ばれ、もう1つは基本的にハッシュと同じです。何が起こっているのか理解するのが難しかったので、例を挙げましょう。あなたは二つの要素と値のフォームを与え、あなたのハッシュ関数があると仮定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%をバケットから削除すると、見積もりが大幅に改善されることを発見しました。彼らはまた、数値を平均化するために別のアルゴリズムを使用しました。論文は数学が重いです。
そして、hyperLogLogアルゴリズムの改良版を示す最近の論文で終わりたいと思います(これまでは、完全に理解する時間はありませんでしたが、後でこの回答を改善する予定です)。