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
. 즉, 문자열이 k
0 인 경우 거의 2^k
요소를 살펴본 것 입니다. 이것이 좋은 출발점입니다. 균등하게 분배되는 요소의 목록을 갖는 0
및 2^k - 1
2 진 표현 제로의 가장 큰 접두사의 최대 수를 셀 수 이것은 당신에게 합리적인 견적을 제공 할 것입니다.
문제는 0
t 에서 균등하게 분포 된 숫자를 가정한다는 2^k-1
것이 너무 어렵다는 것입니다 (우리가 직면 한 데이터는 대부분 숫자가 아니며 거의 균등하게 분포되지 않으며 모든 값 사이에있을 수 있지만 좋은 해싱 함수를 사용 하면 다음과 같이 가정 할 수 있습니다 출력 비트는 균일하게 분포 될 것이고, 가장 해싱 함수 간의 출력해야 0
하고 2^k - 1
( SHA1을 사용하면 사이의 값 수득 0
하고 2^160
지금까지 달성 우리의 최대 카디널리티 독특한 요소 수 추정 수 있다는 것을). 따라서 k
만 저장하여 비트 하나의 크기 log(k)
비트의 단점 단점은 추정치에 큰 차이가 있다는 것입니다.1984 년의 확률 론적 계산 지 (추정은 조금 더 똑똑하지만 여전히 가깝습니다).
LogLog
더 나아 가기 전에 우리는 왜 첫 번째 추정치가 그렇게 크지 않은지를 이해해야합니다. 그 이유는 고주파 0 접두사 요소가 한 번 무작위로 발생하여 모든 것을 망칠 수 있기 때문입니다. 그것을 향상시키는 한 가지 방법은 많은 해시 함수를 사용하고 각 해시 함수에 대해 최대 수를 계산하고 결국 평균을 계산하는 것입니다. 이것은 훌륭한 아이디어로 추정치를 향상시킬 수 있지만 LogLog 용지 는 약간 다른 접근법을 사용했습니다 (아마 해싱이 비싸기 때문에).
그들은 하나의 해시를 사용했지만 두 부분으로 나누었습니다. 하나는 버킷 (총 버킷 수는 2^x
)이고 다른 하나는 기본적으로 해시와 동일합니다. 무슨 일이 일어나고 있는지 알기가 어려웠으므로 예제를 들겠습니다. 당신이 값 양식을 제공 두 가지 요소와 해시 함수가 가정 0
에 2^10
생산이 개 값을 : 344
와 387
. 버킷이 16 개 있다고 결정했습니다. 그래서 당신은 :
0101 011000 bucket 5 will store 1
0110 000011 bucket 6 will store 4
더 많은 버킷을 사용하면 분산이 줄어 듭니다 (공간을 약간 더 사용하지만 여전히 작습니다). 수학 기술을 사용하여 오류 (즉 1.3/sqrt(number of buckets)
) 를 정량화 할 수있었습니다 .
하이퍼 로그
HyperLogLog 는 새로운 아이디어를 도입하지 않지만 대부분 이전 계산을 개선하기 위해 많은 수학을 사용합니다. 연구원들은 버킷에서 가장 큰 숫자의 30 %를 제거하면 추정치가 크게 향상된다는 것을 발견했습니다. 또한 평균을 계산하기 위해 다른 알고리즘을 사용했습니다. 종이는 수학적으로 무겁습니다.
그리고 최신 논문으로 마무리하고 싶습니다 .hyperLogLog 알고리즘 의 향상된 버전 을 보여줍니다 (지금까지는 완전히 이해할 시간이 없었지만 나중에이 대답을 향상시킬 것입니다).