HyperLogLog là một cấu trúc dữ liệu xác suất . Nó đếm số lượng các yếu tố riêng biệt trong một danh sách. Nhưng so với cách làm đơn giản (có một tập hợp và thêm các phần tử vào tập hợp) thì nó thực hiện điều này một cách gần đúng.
Trước khi xem làm thế nào thuật toán HyperLogLog làm điều này, người ta phải hiểu tại sao bạn cần nó. Vấn đề với một cách đơn giản là nó tiêu tốn O(distinct elements)
không gian. Tại sao có một ký hiệu O lớn ở đây thay vì chỉ các yếu tố riêng biệt? Điều này là do các yếu tố có thể có kích cỡ khác nhau. Một yếu tố có thể là 1
một yếu tố khác "is this big string"
. Vì vậy, nếu bạn có một danh sách lớn (hoặc một luồng lớn các yếu tố), nó sẽ chiếm rất nhiều bộ nhớ.
Đếm xác suất
Làm thế nào người ta có thể có được một ước tính hợp lý của một số yếu tố duy nhất? Giả sử rằng bạn có một chuỗi độ dài m
bao gồm {0, 1}
xác suất bằng nhau. Xác suất mà nó sẽ bắt đầu bằng 0, với 2 số không, với số 0 là bao nhiêu? Nó là 1/2
, 1/4
và 1/2^k
. Điều này có nghĩa là nếu bạn đã gặp một chuỗi có k
số không, bạn đã xem qua 2^k
các phần tử. Vì vậy, đây là một điểm khởi đầu tốt. Có một danh sách các yếu tố được phân bổ đồng đều giữa 0
và 2^k - 1
bạn có thể đếm số lượng tiền tố lớn nhất của các số 0 trong biểu diễn nhị phân và điều này sẽ cho bạn một ước tính hợp lý.
Vấn đề là giả định có số phân phối đồng đều từ 0
t 2^k-1
quá khó đạt được (dữ liệu chúng tôi gặp chủ yếu không phải là số, hầu như không bao giờ được phân phối đều và có thể nằm giữa bất kỳ giá trị nào. Nhưng sử dụng hàm băm tốt bạn có thể giả sử rằng các bit đầu ra sẽ được phân phối đồng đều và hầu hết hàm băm có đầu ra giữa 0
và 2^k - 1
( SHA1 cung cấp cho bạn các giá trị giữa 0
và 2^160
). Vì vậy, những gì chúng ta đã đạt được cho đến nay là chúng ta có thể ước tính số lượng phần tử duy nhất với số lượng tối đa của k
bit bằng cách chỉ lưu trữ Một số log(k)
bit kích thước . Nhược điểm là chúng tôi có một phương sai rất lớn trong ước tính của chúng tôi. Một điều tuyệt vời mà chúng tôi gần như đã tạo raƯớc tính giấy xác suất của năm 1984 (nó thông minh hơn một chút với ước tính, nhưng chúng tôi vẫn gần gũi).
Đăng nhập
Trước khi tiến xa hơn, chúng ta phải hiểu tại sao ước tính đầu tiên của chúng ta không tuyệt vời như vậy. Lý do đằng sau đó là một sự xuất hiện ngẫu nhiên của phần tử tiền tố 0 tần số cao có thể làm hỏng mọi thứ. Một cách để cải thiện nó là sử dụng nhiều hàm băm, đếm tối đa cho mỗi hàm băm và cuối cùng là trung bình chúng. Đây là một ý tưởng tuyệt vời, sẽ cải thiện ước tính, nhưng giấy LogLog đã sử dụng một cách tiếp cận hơi khác (có lẽ vì băm là loại đắt tiền).
Họ đã sử dụng một hàm băm nhưng chia nó thành hai phần. Một cái được gọi là xô (tổng số xô là 2^x
) và cái khác - về cơ bản giống như hàm băm của chúng tôi. Thật khó cho tôi để có được những gì đang xảy ra, vì vậy tôi sẽ đưa ra một ví dụ. Giả sử bạn có hai phần tử và hàm băm của bạn cung cấp biểu mẫu giá trị 0
để 2^10
tạo ra 2 giá trị: 344
và 387
. Bạn đã quyết định có 16 thùng. Vì vậy, bạn có:
0101 011000 bucket 5 will store 1
0110 000011 bucket 6 will store 4
Bằng cách có nhiều thùng hơn, bạn giảm phương sai (bạn sử dụng nhiều không gian hơn một chút, nhưng nó vẫn còn nhỏ). Sử dụng các kỹ năng toán học, họ có thể định lượng được lỗi (đó là 1.3/sqrt(number of buckets)
).
HyperLogLog
HyperLogLog không giới thiệu bất kỳ ý tưởng mới nào, nhưng chủ yếu sử dụng rất nhiều toán học để cải thiện ước tính trước đó. Các nhà nghiên cứu đã phát hiện ra rằng nếu bạn loại bỏ 30% số lượng lớn nhất khỏi các thùng, bạn sẽ cải thiện đáng kể ước tính. Họ cũng sử dụng một thuật toán khác để lấy số trung bình. Bài báo nặng về toán học.
Và tôi muốn kết thúc với một bài báo gần đây, trong đó cho thấy một phiên bản cải tiến của thuật toán hyperLogLog (cho đến bây giờ tôi không có thời gian để hiểu đầy đủ về nó, nhưng có lẽ sau này tôi sẽ cải thiện câu trả lời này).