HyperLogLog 알고리즘은 어떻게 작동합니까?


172

나는 최근 여가 시간에 다른 알고리즘에 대해 배웠으며 매우 흥미로운 것으로 보이는 HyperLogLog 알고리즘이라고합니다.이 목록에는 몇 개의 고유 항목이 있는지 추정합니다.

이것은 "카디널리티"값을 보았을 때 MySQL 시절로 돌아 왔기 때문에 특히 흥미로 웠습니다.

그래서 배열에 몇 개의 고유 항목이 있는지 계산하는 알고리즘을 O ( n ) 로 작성하는 방법을 알고 있습니다. 나는 이것을 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;
}

그러나 문제는 내 알고리즘이 O ( n ) 동안 많은 메모리를 사용한다는 것입니다 (값을에 저장 Table).

나는 O ( n ) 시간 내에 목록에서 중복을 계산 하고 최소 메모리를 사용 하는 방법에 대해이 논문을 읽었습니다 .

비트를 해시하고 계산하여 특정 확률 내에서 (목록이 고르게 분포되어 있다고 가정) 목록의 고유 항목 수를 추정 할 수 있다고 설명합니다.

논문을 읽었지만 이해할 수없는 것 같습니다. 누군가 더 평신도의 설명을 줄 수 있습니까? 해시가 무엇인지 알고 있지만이 HyperLogLog 알고리즘에서 어떻게 사용되는지 이해하지 못합니다.


4
이 백서 ( research.google.com/pubs/pub40671.html )에는 HyperLogLog 알고리즘과 개선 사항도 요약되어 있습니다. 원래 종이보다 이해하기가 더 쉽다고 생각합니다.
zhanxw

11
명명법에 대한 힌트 : 일부 사람들은 단어 집합을 사용하여 고유 한 항목 모음을 설명 합니다. 그들에게 대신 목록이나 배열이라는 용어를 사용했다면 질문이 더 합리적 일 수 있습니다.
Paddy3118

답변:


153

이 알고리즘의 주요 요령은 임의의 정수 스트림을 관찰하고 이진 표현이 알려진 접두어로 시작하는 정수를 보는 경우 스트림의 카디널리티가 2 ^ (접두사의 크기) 일 가능성이 높다는 것입니다 .

즉, 임의의 정수 스트림에서 숫자의 약 50 % (2 진)는 "1"로 시작하고 25 %는 "01"로 시작하고 12,5 %는 "001"로 시작합니다. 즉, 임의 스트림을 관찰하고 "001"을 볼 경우이 스트림의 카디널리티가 8 일 가능성이 높습니다.

접두사 "00..1"에는 특별한 의미가 없습니다. 대부분의 프로세서에서 이진수로 가장 중요한 비트를 쉽게 찾을 수 있기 때문입니다.

물론 하나의 정수만 관찰하면이 값이 잘못 될 가능성이 높습니다. 이것이 알고리즘이 스트림을 "m"독립 서브 스트림으로 나누고 각 서브 스트림의 보이는 "00 ... 1"접두사의 최대 길이를 유지하는 이유입니다. 그런 다음 각 서브 스트림의 평균값을 취하여 최종 값을 추정합니다.

이것이이 알고리즘의 주요 아이디어입니다. 누락 된 세부 사항 (예 : 낮은 추정값에 대한 수정)이 있지만 모두 논문에 잘 기록되어 있습니다. 끔찍한 영어 죄송합니다.


"이 스트림의 카디널리티가 8 일 가능성이 더 높습니다"000이 예상되는 시도 횟수 2 ^ 3을 의미하는 이유를 설명해 주시겠습니까? 나는 우리가 적어도 3 개의 0으로 런을하고 4 개의 0으로 런을하지 않는다고 가정하고 시행 횟수에 대한 수학 기대치를 계산하려고 시도했습니다.
yura

5
내가 이것을 읽을 때까지 종이를 이해하지 못했습니다. 이제 말이됩니다.
josiah

5
@ yura 나는 그것이 매우 오래된 의견이라는 것을 알고 있지만 다른 사람들에게 유용 할 수 있습니다. 그는 "이것은 임의의 정수 스트림에서 (...) 12,5 %는"001 "로 시작한다"고 말했다. 12,5 %가 전체 스트림의 1/8을 나타내므로 가능한 카디널리티는 8입니다.
브라운 마 그린

111

HyperLogLog는 확률 적 데이터 구조 입니다. 목록에서 고유 한 요소 수를 계산합니다. 그러나 (세트를하고 요소를 세트에 추가하는) 간단한 방법과 비교하면 대략적인 방식 으로이 작업을 수행합니다.

HyperLogLog 알고리즘이이를 수행하는 방법을 살펴보기 전에 필요한 이유를 이해해야합니다. 간단한 방법의 문제점 O(distinct elements)은 공간을 소비한다는 것 입니다. 왜 별개의 요소가 아닌 큰 O 표기법이 있습니까? 요소의 크기가 다를 수 있기 때문입니다. 한 요소는 1다른 요소 일 수 있습니다 "is this big string". 따라서 거대한 목록 (또는 거대한 요소 스트림)이 있으면 많은 메모리가 필요합니다.


확률 계산

여러 가지 독특한 요소를 어떻게 합리적으로 추정 할 수 있습니까? 동일한 확률 m로 구성된 길이의 문자열이 있다고 가정하십시오 {0, 1}. 0으로 시작하고 2 0으로 시작하고 k 0으로 시작될 확률은 얼마입니까? 그것은이다 1/2, 1/4하고 1/2^k. 즉, 문자열이 k0 인 경우 거의 2^k요소를 살펴본 것 입니다. 이것이 좋은 출발점입니다. 균등하게 분배되는 요소의 목록을 갖는 02^k - 12 진 표현 제로의 가장 큰 접두사의 최대 수를 셀 수 이것은 당신에게 합리적인 견적을 제공 할 것입니다.

문제는 0t 에서 균등하게 분포 된 숫자를 가정한다는 2^k-1것이 너무 어렵다는 것입니다 (우리가 직면 한 데이터는 대부분 숫자가 아니며 거의 균등하게 분포되지 않으며 모든 값 사이에있을 수 있지만 좋은 해싱 함수를 사용 하면 다음과 같이 가정 할 수 있습니다 출력 비트는 균일하게 분포 될 것이고, 가장 해싱 함수 간의 출력해야 0하고 2^k - 1( SHA1을 사용하면 사이의 값 수득 0하고 2^160지금까지 달성 우리의 최대 카디널리티 독특한 요소 수 추정 수 있다는 것을). 따라서 k만 저장하여 비트 하나의 크기 log(k)비트의 단점 단점은 추정치에 큰 차이가 있다는 것입니다.1984 년의 확률 론적 계산 지 (추정은 조금 더 똑똑하지만 여전히 가깝습니다).

LogLog

더 나아 가기 전에 우리는 왜 첫 번째 추정치가 그렇게 크지 않은지를 이해해야합니다. 그 이유는 고주파 0 접두사 요소가 한 번 무작위로 발생하여 모든 것을 망칠 수 있기 때문입니다. 그것을 향상시키는 한 가지 방법은 많은 해시 함수를 사용하고 각 해시 함수에 대해 최대 수를 계산하고 결국 평균을 계산하는 것입니다. 이것은 훌륭한 아이디어로 추정치를 향상시킬 수 있지만 LogLog 용지 는 약간 다른 접근법을 사용했습니다 (아마 해싱이 비싸기 때문에).

그들은 하나의 해시를 사용했지만 두 부분으로 나누었습니다. 하나는 버킷 (총 버킷 수는 2^x)이고 다른 하나는 기본적으로 해시와 동일합니다. 무슨 일이 일어나고 있는지 알기가 어려웠으므로 예제를 들겠습니다. 당신이 값 양식을 제공 두 가지 요소와 해시 함수가 가정 02^10생산이 개 값을 : 344387. 버킷이 16 개 있다고 결정했습니다. 그래서 당신은 :

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

더 많은 버킷을 사용하면 분산이 줄어 듭니다 (공간을 약간 더 사용하지만 여전히 작습니다). 수학 기술을 사용하여 오류 (즉 1.3/sqrt(number of buckets)) 를 정량화 할 수있었습니다 .

하이퍼 로그

HyperLogLog 는 새로운 아이디어를 도입하지 않지만 대부분 이전 계산을 개선하기 위해 많은 수학을 사용합니다. 연구원들은 버킷에서 가장 큰 숫자의 30 %를 제거하면 추정치가 크게 향상된다는 것을 발견했습니다. 또한 평균을 계산하기 위해 다른 알고리즘을 사용했습니다. 종이는 수학적으로 무겁습니다.


그리고 최신 논문으로 마무리하고 싶습니다 .hyperLogLog 알고리즘향상된 버전 을 보여줍니다 (지금까지는 완전히 이해할 시간이 없었지만 나중에이 대답을 향상시킬 것입니다).


2
나는 이론적 k zeroes으로 특별한 것이 아니라고 가정 합니다. 대신 찾을 수 k ones있고 논리는 동일하거나 심지어 k length문자열을 찾을 수 {0,1}있지만 그러한 문자열 중 하나를 가져 와서 붙일 수 있습니까? 이진 문자열의 경우 모두 1 / 2 ^ k의 확률이 동일하기 때문에?
user881300

3
HyperLogLog는 가장 큰 숫자의 30 %를 제거하지 않습니다. 이것은 LogLog 논문에 설명 된 SuperLogLog 알고리즘의 아이디어입니다. HyperLogLog 알고리즘의 주요 아이디어는 SuperLogLog 및 LogLog에서 사용하는 기하 평균 대신 고조파 평균을 사용하여 2의 거듭 제곱을 평균화하는 것입니다.
otmar

21

직감은 입력이 큰 임의의 숫자 세트 (예 : 해시 값) 인 경우 범위에 균등하게 분배되어야합니다. 1024까지의 값을 나타 내기 위해 범위가 최대 10 비트라고 가정합니다. 그런 다음 최소값을 관찰했습니다. 10이라고 가정하면 카디널리티는 약 100으로 추정됩니다 (10 × 100 ≈ 1024).

물론 실제 논리에 대한 논문을 읽으십시오.

샘플 코드에 대한 또 다른 좋은 설명은 여기에서 찾을 수 있습니다.
Damn Cool Algorithms : Cardinality Estimation-Nick 's Blog


3
멋진 알고리즘 블로그 게시물에 대한 링크를 위해 투표했습니다. 알고리즘을 이해하는 데 정말 도움이되었습니다.
Igor Serebryany
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.