Back to Home

Bloom Filter

Giới thiệu

Bloom Filter là một cấu trúc dữ liệu có tính chất xác suất dùng để kiểm tra một phần tử có nằm trong một tập hợp hay không. Nó rất hiệu quả về mặt không gian lưu trữ và tốc độ. Bloom filter có thể trả lời hai câu hỏi chính:

  • Phần tử có thể nằm trong tập hợp (tính chất xác suất)

  • Hoặc, phần tử chắn chắn không nằm trong tập hợp

Bloom Filter được ứng dụng trong blockchain để lọc các transaction nhanh chóng trong các block. Bloom filter cũng được dùng trong các cơ sở dữ liệu CassandraBigtable.

Phương pháp hoạt động

Cho bloom filter được khởi tạo là một chuỗi bit độ dài mm các giá trị 00:

BF={0,0,,0m}BF = \{\underbrace{0,0,\dots,0}_{m}\}

Thêm một phần tử xx:

  • Dùng kk hàm hash phân biệt h1,h2,,hkh_1,h_2,\dots,h_k: để tính giá trị các giá trị index idxi=hi(x)modmidx_i = h_i(x) \mod m

  • Lần lượt set các phần tử ở vị trí%leaf%idxiidx_icủa BFBF bằng 11: BF[idxi]=1BF[idx_i] = 1

Tìm kiếm phần tử ss

  • Dùng kk hàm hash ở trên để tính các giá trị index cho giá trị ss: idsi=hi(s)modmids_i = h_i(s) \mod m

  • Lần lượt kiếm tra tất cả các giá trị BF[idsi]BF[ids_i]:

    • Nếu tồn tại bất kỳ một giá trị nào là 00 thì kết luận phần tử ss chắc chắn không nằm trong tập hợp.

    • Ngược lại, phần tử ss có thể nằm trong tập hợp.

Demo

Cách chọn số lượng filter kk và kích thước filter mm

Để tối ưu hóa Bloom Filter, việc chọn số lượng hàm băm kk và kích thước mảng bit cho filter mm là cực kỳ quan trọng. Nếu kk quá nhỏ, tỷ lệ dương tính giả (false positive) sẽ cao; nếu kk quá lớn, mảng bit sẽ nhanh chóng bị lấp đầy bởi các số 1, cũng dẫn đến tăng tỷ lệ sai sót và tốn chi phí tính toán.

Gỉa sử ta có:

  • nn: Số lượng phần tử dự kiến sẽ thêm vào bộ lọc.

  • mm: Kích thước của mảng bit.

  • kk: Số lượng hàm băm (hash functions).

Xác suất để một bit cụ thể vẫn bằng 0 sau khi chèn nn phần tử là:

11m1 - \frac 1 m

ổng số lần băm đã thực hiện là k×nk \times n lần. Vì các hàm băm được giả định là độc lập và phân phối đều, xác suất để bit đó vẫn bằng 0 sau knkn lần băm là:

p=(11m)kn=((11m)m)knmekn/mp = \left( 1 - \frac{1}{m} \right)^{kn}\\ = \left( \left( 1 - \frac{1}{m} \right)^m \right)^{\frac{kn}{m}} \approx e^{-kn/m}

Từ đó, xác suất để tất cả kk vị trí băm của một phần tử mới đều bằng 1 (dẫn đến False Positive) là:

P=(1p)k(1ekn/m)kP = (1 - p)^k \approx (1 - e^{-kn/m})^k

Ta có, như đã đề cập ở trên thì p=ekn/mp = e^{-kn/m} suy ra:

knm=ln(p)    k=mnln(p)\frac {kn} m = -\ln(p) \implies k = -\frac{m}{n} \ln(p)

Thay giá trị kk vừa tìm được vào công thức của PP:

P=(1p)mnln(p)P = (1 - p)^{-\frac{m}{n} \ln(p)}

Để tối thiểu hóa PP, ta có thể tối thiểu hóa giá trị logarit của nó (vì hàm ln\ln là hàm đồng biến):

ln(P)=mnln(p)ln(1p)ln(P) = -\frac{m}{n} \ln(p) \ln(1 - p)

Để tìm cực trị, ta đặt f(p)=ln(p)ln(1p)f(p) = \ln(p) \ln(1 - p) và lấy đạo hàm theo pp:

f(p)=1pln(1p)+ln(p)11p=ln(1p)pln(p)1pf'(p) = \frac{1}{p} \ln(1 - p) + \ln(p) \frac{-1}{1 - p} = \frac{\ln(1 - p)}{p} - \frac{\ln(p)}{1 - p}

Giải phương trình để đạo hàm bằng 00:

ln(1p)p=ln(p)1p(1p)ln(1p)=pln(p)\frac{\ln(1 - p)}{p} = \frac{\ln(p)}{1 - p}\\ (1 - p) \ln(1 - p) = p \ln(p)

Phương trình này có dạng g(1p)=g(p)g(1-p) = g(p) với g(x)=xln(x)g(x) = x \ln(x). Do tính chất đối xứng, nghiệm duy nhất của phương trình này trong khoảng (0,1)(0, 1) là:

1p=p    p=121 - p = p \implies p = \frac 1 2

Thay p=1/2p=1/2 vào công thức ekn/me^{-kn/m} lấy log 2 vế, giải ra ta có:

knm=ln(2)    k=mnln(2)    k0.693×mn\frac {kn} m = \ln (2) \implies k = \frac m n \ln(2) \implies k \approx 0.693 \times \frac m n

Với một giá trị mmnn cho trước, tỷ lệ sai sót PP sẽ đạt giá trị nhỏ nhất khi:

k=mnln(2)0.693×mnk = \frac{m}{n} \ln(2) \approx 0.693 \times \frac{m}{n}

Thông thường trong thực tế, bạn sẽ xác định trước tỷ lệ sai sót chấp nhận được (ví dụ P=0.01P = 0.01 hay 1%) và số lượng phần tử nn. Khi đó, kích thước mảng bit mm cần thiết được tính bằng:

m=nlnP(ln2)2m = -\frac{n \ln P}{(\ln 2)^2}

Nghĩa là:

  • Để đạt tỷ lệ sai sót 1% (P=0.01P = 0.01): Bạn cần khoảng 10 bit cho mỗi phần tử (m/n10m/n \approx 10).

  • Để đạt tỷ lệ sai sót 0.1% (P=0.001P = 0.001): Bạn cần khoảng 14 bit cho mỗi phần tử.

Ví dụ: Giả sử có khoảng 1 triệu phần tử và muốn tỷ lệ sai số khoảng 2% thì:

Sử dụng công thức: m=nlnP(ln2)2m = -\frac{n \ln P}{(\ln 2)^2}

  • P=0,02    ln(0,02)3.9P = 0,02 \implies \ln(0,02) \approx -3.9

  • (ln2)20.48(\ln 2)^2 \approx 0.48

m=1.000.000×(3.9)0.488.1 Megabits8 MB RAMm = -\frac{1.000.000 \times (-3.9)}{0.48} \approx 8.1 \text{ Megabits} \approx 8 \text { MB RAM}

k=mnln(2)6.64    k=7k = \frac m n \ln(2) \approx 6.64 \implies k =7

Comments

0/300

Leave name/email blank to comment anonymously

No comments yet. Be the first to comment!