1. 程式人生 > 其它 >Data Structure 隨記(1)—— Bloom Filters

Data Structure 隨記(1)—— Bloom Filters

Data Structure 隨記(1)

目錄

Bloom Filters

一句話解釋作用:“如何判斷一個元素是否在某個集合中?“

Bloom Filters 中文名布隆過濾器,好像以前在某個導論課上有老師提過,但是時過境遷現在已經完全忘了,這幾天輔導的時候突然又遇到了這個資料結構,遂記錄。 Bloom Filters 的內容大部分參考 UC Berkeley CS170 的 Note10,ref here

如果鍵值的分佈是未知的,使用一個特定的雜湊函式 \(h\) 可能會產生不利 (adverse) 的影響:\(h\)

可能會誤判鍵值之間的關係,使得雜湊表的填充並不均勻。這顯然不符合我們的預期,所以我們需要提出一些解決方案, Bloom Filters 就是一種可行的方案,利用不同的雜湊函式 \(\{h_i\}\) 去對映每個鍵值。使用多種雜湊函式可以在使用簡單的雜湊函式的同時最小化某些特定的雜湊函式(可以理解為設計的很爛的雜湊函式)對於雜湊表的影響。

雜湊表實際上能實現判斷某個元素是否存在集合中,那設計 Bloom Filters 的 Motivation 是什麼?

Bloom Filters 的設計目的是為了構建一個空間效率高的資料結構去解決“集合成員”的問題。因此,為了最大化空間效率,正確率在一定程度上被犧牲了。如果一個元素不在集合中, Bloom Filters 可能給出一個錯誤的答案(稱為 false positive

假陽),但是如果元素存在集合中, Bloom Filters 一定會給出正確答案(這裡我們只考慮 Standard Bloom Filters,即不考慮刪除操作)。並且我們可以證明 Bloom Filters 假陽的概率足夠低。

前排補充:可以省略的實際應用

Bloom Filters 的一個典型應用是網路快取。一個 ISP (Internet Service Provider) 可能會保留幾層特定的快取,以加快常用網頁的載入速度,特別是對於大型資料物件,如影象和視訊。如果一個客戶要求一個特定的URL,那麼伺服器需要迅速確定所要求的網頁是否在其快取中。假陽性雖然不可取,但是如果事實證明被認為在快取中的頁面不在那裡,將它從其原始的URL載入,而且最終的 "penalty "並不比一開始就沒有快取差多少,那麼假陽性也是可以接受的。

接下來是正式的描述:我們想要表示來自非常大的集合 \(U\) ,包含\(n\)個元素的集合 \(S=\left\{s_1, \ldots, s_n\right\}\),其中 \(|U |=u>>n\)。(為了更好的理解,你可以將 \(U\) 視為一組 URL,將 \(n\) 視為快取大小,並將 \(S\) 視為當前快取中的那些網頁的 URL。)我們希望支援插入和成員資格查詢(“給定元素 \(x \in U\) 判斷 \(x \in S\) ”)且:

  1. 如果答案是否定的,那麼 \(x \notin S\)
  2. 如果答案是肯定的,那麼 \(x\) 可能在 \(S\) 中也可能不在 \(S\) 中,但是 \(x\notin S\)(假陽)的概率很低。

插入和成員資格查詢操作的時間複雜度應該都為常數 \(\Theta(1)\)

Bloom Filters 是一個包含 \(m\) 位的位向量 \(B\),具有 \(k\) 個獨立的雜湊函式 \(h_1, \ldots, h_k\),雜湊函式用於將 \(U\) 中的每個值鍵對映到集合 \(R_m=\{0,1 , \ldots, m-1\}\)。 我們假設每個雜湊函式 \(h_i\) 以相同的概率將隨機選擇的鍵值 \(x \in U\) 對映到 \(R_m\) 的每個元素。 由於雜湊函式是獨立的,因此向量 \(\left(h_1(x), \ldots, h_k(x)\right)\) 同樣可能是來自的元素的 \(m^k k\) 元組中的任何一個 \(R_m\)。 最初,\(B\) 的所有 \(m\) 位都設定為 0 。

  • \(x\) 插入 \(S\)。 計算 \(h_1(x), \ldots, h_k(x)\) 並設定 \(B\left[h_1(x)\right]=B\left[h_2(x)\right]=\cdots=\) \(B\left [h_k(x)\right]=1\)
  • 查詢 \(x\) 是否屬於 \(S\)。計算 \(h_1(x), \ldots, h_k(x)\) ,如果 \(B\left[h_1(x)\right]=B\left[h_2(x)\right]=\cdots=\) \(B\left [h_k(x)\right]=1\) 那麼答案是肯定的,否則是否定的。

Bloom Filters 很受工程師的歡迎,因為它用很少的工作就能實現“可證明”的良好效能(見參考文獻的分析):簡單的雜湊函式,簡單的演算法(沒有碰撞處理等),有效地利用空間。Bloom Filters 的主要缺點是很難用 \(S\) 中的鍵值儲存額外的資訊。

Example

這是一個小例子,僅用來說明 Bloom Filters 如何工作的,以及對應假陽性的可能。

其唯一目的是說明假陽性的可能性。選擇\(m=5\)(位元數)和\(k=2\)(雜湊函式的數量)。

\[\begin{aligned} & h_1(x)=x \bmod 5 \\ & h_2(x)=(2 x+3) \bmod 5 \end{aligned} \]

我們首先初始化 Bloom filter \(B[1 . .5]\),然後插入元素 \(9\)\(11\)

\[\begin{array}{l|cc|c|c|c|c|c|} & h_1(x) & h_2(x) & & & B & & \\ \hline \text{Initialize}: & & & 0 & 0 & 0 & 0 & 0 \\ \hline \mathrm{Insert}\; 9: & 4 & 1 & 0 & \color{Salmon}{1} & 0 & 0 & \color{Salmon}{1} \\ \hline \mathrm{Insert}\; 11: & 1 & 0 & \color{Salmon}{1} & 1 & 0 & 0 & 1 \\ \hline \end{array} \]

現在我們嘗試進行兩次 Query 操作:

\[\begin{array}{lccl} & h_1(x) & h_2(x) & \text{Answer} \\ \mathrm{Query}\; 15: & 0 & 3 & \text{No, not in $B$ (correct answer)} \\ \mathrm{Query}\; 16: & 1 & 0 & \text{Yes, in $B$ (wrong answer: false positive)} \\ \end{array} \]

注意⚠️:\(16\) 從沒有插入到 Bloom Filters 中。

數學分析

見課件。