HyperLogLogアルゴリズムはどのように機能しますか?


172

最近は暇なときにさまざまなアルゴリズムについて学んでいます。私が遭遇した非常に興味深いと思われるアルゴリズムはHyperLogLogアルゴリズムと呼ばれ、リストに含まれる一意のアイテムの数を推定します。

これは、「カーディナリティ」の値(最近までは、推定されていないと計算されていたと私は常に想定していました)を見たMySQL時代に戻ったので、特に興味深いものでした。

そのため、配列内の一意のアイテムの数を計算するアルゴリズムをOn)で記述する方法を知っています。私はこれをJavaScriptで書いた:

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;
}

しかし問題は、私のアルゴリズムはOn)が大量のメモリを使用する(に値を格納するTable)ことです。

私は、On)時間でリスト内の重複をカウントし、最小限のメモリを使用する方法についてこのペーパーを読んでいます。

それは、ビットまたは何かをハッシュおよびカウントすることにより、特定の確率内で(リストが均等に分散されていると仮定して)推定できるリスト内の一意のアイテムの数を説明します。

論文は読みましたが、理解できないようです。誰かがもっと素人の説明をすることができますか?私はハッシュが何であるかを知っていますが、このHyperLogLogアルゴリズムでどのように使用されるかわかりません。


4
このペーパー(research.google.com/pubs/pub40671.html)では、HyperLogLogアルゴリズムといくつかの改善点についてもまとめています。元の論文より理解しやすいと思います。
zhanxw 2013年

11
用語のヒント:一部の人々は、単語セットを使用して、ユニークなアイテムのコレクションを説明します。彼らにとって、代わりにリストまたは配列という用語を使用した場合、あなたの質問はより意味をなすでしょう。
Paddy3118 2013年

回答:


153

このアルゴリズムの背後にある主なトリックは、ランダムな整数のストリームを観察して、バイナリ表現が既知のプレフィックスで始まる整数を見る場合、ストリームのカーディナリティが2 ^(プレフィックスのサイズ)である可能性が高いことです。 。

つまり、整数のランダムストリームでは、数値の〜50%(バイナリ)は「1」で始まり、25%は「01」で始まり、12.5%は「001」で始まります。つまり、ランダムストリームを観察して「001」を表示すると、このストリームのカーディナリティが8である可能性が高くなります。

(接頭辞 "00..1"には特別な意味はありません。ほとんどのプロセッサで2進数の最上位ビットを簡単に見つけることができるからです)

もちろん、整数が1つしかない場合は、この値が間違っている可能性が高くなります。そのため、アルゴリズムはストリームを「m」個の独立したサブストリームに分割し、各サブストリームの見られる「00 ... 1」プレフィックスの最大長を維持します。次に、各サブストリームの平均値を取ることにより、最終的な値を推定します。

それがこのアルゴリズムの主な考え方です。いくつかの詳細が欠けています(たとえば、推定値が低い場合の修正など)が、それはすべて論文によく書かれています。ひどい英語でごめんなさい。


「このストリームのカーディナリティが8である可能性が高くなります」000が予想される試行回数2 ^ 3を意味する理由を説明していただけますか。ゼロが3つあるランが1つあり、ゼロが4つあるランがないと仮定して、試行回数の数学期待値を計算しようとしました...
yura

5
私がこれを読むまで、その論文はよくわかりませんでした。今では理にかなっています。
ジョサイア2014

5
@yuraとても古いコメントだと思いますが、他の人にも役立つかもしれません。「つまり、ランダムな整数のストリームでは、(...)12.5%が「001」で始まります。」12.5%がストリーム全体の1/8を表すため、推定カーディナリティは8です。
ブラウンマグリン

111

HyperLogLogは、確率的データ構造です。リスト内の個別の要素の数をカウントします。しかし、それを行う単純な方法(セットを持ち、要素をセットに追加する)と比較すると、これはおおよその方法で行われます。

HyperLogLogアルゴリズムがこれをどのように行うかを調べる前に、なぜそれが必要なのかを理解する必要があります。簡単な方法の問題は、O(distinct elements)スペースを消費することです。なぜ明確な要素だけでなく、大きなO表記があるのですか?これは、要素のサイズが異なる可能性があるためです。1つの要素を1別の要素にすることができます"is this big string"。したがって、巨大なリスト(または要素の巨大なストリーム)がある場合、大量のメモリが必要になります。


確率的カウント

いくつかの一意の要素の合理的な見積もりを取得するにはどうすればよいですか?等しい確率mで構成される長さの文字列があるとします{0, 1}。0、2つのゼロ、kのゼロで始まる確率はどれくらいですか?それは1/21/41/2^k。これは、kゼロの文字列に遭遇した場合、ほぼ2^k要素を調べたことを意味します。したがって、これは良い出発点です。要素のリストが均等に分散され0てい2^k - 1て、バイナリ表現でゼロの最大プレフィックスの最大数を数えることができ、これにより妥当な見積もりが得られます。

問題は、0t からの数値が均等に分散しているという仮定は2^k-1実現が難しいことです(遭遇したデータはほとんど数値ではなく、ほとんど均等に分散されておらず、任意の値の間にある可能性があります。しかし、適切なハッシュ関数を使用すると、出力ビットが均等に分散し、最もられるハッシュ関数の間に出力している02^k - 1SHA1は、あなたが間の値を与える02^160)を。だから何我々はこれまでに達成したことは、我々は、最大カーディナリティとユニークな要素の数を推定することができるということであるkだけで保存することにより、ビットサイズlog(k)ビットの数が1つあります。欠点は、推定値に大きなばらつきがあることです。1984年の確率論的カウンティングペーパー(見積もりの​​方が少し賢明ですが、それでも私たちは近いです)。

LogLog

先に進む前に、最初の見積もりがそれほど大きくない理由を理解する必要があります。その背後にある理由は、高周波の0プレフィックス要素が1回ランダムに発生すると、すべてが損なわれる可能性があるためです。それを改善する1つの方法は、多くのハッシュ関数を使用し、各ハッシュ関数の最大数を数え、最終的にそれらを平均することです。これは優れたアイデアであり、見積もりは改善されますが、LogLogペーパーでは少し異なるアプローチが使用されました(おそらくハッシュが一種の高価なため)。

彼らは1つのハッシュを使用しましたが、2つの部分に分割しました。1つはバケット(バケットの総数は2^x)と呼ばれ、もう1つは基本的にハッシュと同じです。何が起こっているのか理解するのが難しかったので、例を挙げましょう。あなたは二つの要素と値のフォームを与え、あなたのハッシュ関数があると仮定02^10生産さ2つの値を:344387。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アルゴリズムの改良版を示す最近の論文で終わりたいと思います(これまでは、完全に理解する時間はありませんでしたが、後でこの回答を改善する予定です)。


2
理論的にk zeroesは特別なことではないと思います。あなたは代わりに探すことができk ones、ロジックは同じであるか、またはk length文字列を探すことさえできます{0,1}が、そのような文字列を1つ取り、それに固執しますか?そのようなバイナリ文字列の場合、それらすべてが1/2 ^ kの等しい確率を持っているからですか?
user881300

3
HyperLogLogは最大数の30%を削除しません。これは、LogLogペーパーでも説明されているSuperLogLogアルゴリズムの考え方です。HyperLogLogアルゴリズムの主なアイデアは、SuperLogLogおよびLogLogで使用されるような幾何平均の代わりに、調和平均を使用して2の累乗を平均化することです。
otmar 2016年

21

直感は、入力が大量の乱数(ハッシュ値など)である場合、範囲全体に均等に分布する必要があるということです。1024までの値を表すために範囲が最大10ビットであるとしましょう。次に、最小値を観察しました。それが10だとしましょう。その場合、カーディナリティーは約100(10×100≈1024)と推定されます。

もちろん本当の論理については、この論文を読んでください。

サンプルコードのもう1つの良い説明は、こちらにあります。
くそークールアルゴリズム:カーディナリティ推定-Nickのブログ


3
いまいましいクールなアルゴリズムのブログ投稿へのリンクに賛成。それは本当にアルゴリズムを理解するのに役立ちました。
Igor Serebryany 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.