<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # Bloom Filter ## 方法介紹 ### 一、什么是Bloom Filter Bloom Filter,被譯作稱布隆過濾器,是一種空間效率很高的隨機數據結構,Bloom filter可以看做是對bit-map的擴展,它的原理是: - 當一個元素被加入集合時,通過K個Hash函數將這個元素映射成一個位陣列(Bit array)中的K個點,把它們置為1**。檢索時,我們只要看看這些點是不是都是1就(大約)知道集合中有沒有它了: - 如果這些點有任何一個0,則被檢索元素一定不在; - 如果都是1,則被檢索元素很可能在。 其可以用來實現數據字典,進行數據的判重,或者集合求交集。 但Bloom Filter的這種高效是有一定代價的:在判斷一個元素是否屬于某個集合時,有可能會把不屬于這個集合的元素誤認為屬于這個集合(false positive)。因此,Bloom Filter不適合那些“零錯誤”的應用場合。而在能容忍低錯誤率的應用場合下,Bloom Filter通過極少的錯誤換取了存儲空間的極大節省。 #### 1.1、集合表示和元素查詢 下面我們具體來看Bloom Filter是如何用位數組表示集合的。初始狀態時,Bloom Filter是一個包含m位的位數組,每一位都置為0。 ![](../images/9/9.3/9.3.1.jpg) 為了表達S={x<sub>1</sub>, x<sub>2</sub>,…,x<sub>n</sub>}這樣一個n個元素的集合,Bloom Filter使用k個相互獨立的哈希函數(Hash Function),它們分別將集合中的每個元素映射到{1,…,m}的范圍中。對任意一個元素x,第i個哈希函數映射的位置h<sub>i</sub>(x)就會被置為1(1≤i≤k)。注意,如果一個位置多次被置為1,那么只有第一次會起作用,后面幾次將沒有任何效果。在下圖中,k=3,且有兩個哈希函數選中同一個位置(從左邊數第五位,即第二個“1“處)。 ![](../images/9/9.3/9.3.2.jpg) 在判斷y是否屬于這個集合時,我們對y應用k次哈希函數,如果所有h<sub>i</sub>(y)的位置都是1(1≤i≤k),那么我們就認為y是集合中的元素,否則就認為y不是集合中的元素。下圖中y<sub>1</sub>就不是集合中的元素(因為y1有一處指向了“0”位)。y<sub>2</sub>或者屬于這個集合,或者剛好是一個false positive。 ![](../images/9/9.3/9.3.3.jpg) #### 1.2、錯誤率估計 前面我們已經提到了,Bloom Filter在判斷一個元素是否屬于它表示的集合時會有一定的錯誤率(false positive rate),下面我們就來估計錯誤率的大小。在估計之前為了簡化模型,我們假設kn<m且各個哈希函數是完全隨機的。當集合S={x<sub>1</sub>, x<sub>2</sub>,…,x<sub>n</sub>}的所有元素都被k個哈希函數映射到m位的位數組中時,這個位數組中某一位還是0的概率是: ![img](http://chart.apis.google.com/chart?cht=tx&chl=p'=\\left(1-\\frac{1}{m}\\right)^{kn}\\approx e^{-kn/m}) 其中1/m表示任意一個哈希函數選中這一位的概率(前提是哈希函數是完全隨機的),(1-1/m)表示哈希一次沒有選中這一位的概率。要把S完全映射到位數組中,需要做kn次哈希。某一位還是0意味著kn次哈希都沒有選中它,因此這個概率就是(1-1/m)的kn次方。令p = e<sup>-kn/m</sup>是為了簡化運算,這里用到了計算e時常用的近似: ![img](http://chart.apis.google.com/chart?cht=tx&chl=\\lim\\limits_{x\\rightarrow\\infty}\\left(1-\\frac{1}{x}\\right)^{-x}=e) 令ρ為位數組中0的比例,則ρ的數學期望E(ρ)= p’。在ρ已知的情況下,要求的錯誤率(false positive rate)為: ![img](http://chart.apis.google.com/chart?cht=tx&chl=(1-\\rho)^k\\approx(1-p')^k\\approx(1-p)^k) (1-ρ)為位數組中1的比例,(1-ρ)<sup>k</sup>就表示k次哈希都剛好選中1的區域,即false positive rate。上式中第二步近似在前面已經提到了,現在來看第一步近似。p’只是ρ的數學期望,在實際中ρ的值有可能偏離它的數學期望值。M. Mitzenmacher已經證明<sup>[2]</sup> ,位數組中0的比例非常集中地分布在它的數學期望值的附近。因此,第一步的近似得以成立。分別將p和p’代入上式中,得: ![img](http://chart.apis.google.com/chart?cht=tx&chl=f'=\\left(1-\\left(1-\\frac{1}{m}\\right)^{kn}\\right)^k=(1-p')^k) ![img](http://chart.apis.google.com/chart?cht=tx&chl=f=\\left(1-e^{-kn/m}\\right)^k=(1-p)^k) 相比p’和f’,使用p和f通常在分析中更為方便。 #### 1.3、最優的哈希函數個數 既然Bloom Filter要靠多個哈希函數將集合映射到位數組中,那么應該選擇幾個哈希函數才能使元素查詢時的錯誤率降到最低呢?這里有兩個互斥的理由:如果哈希函數的個數多,那么在對一個不屬于集合的元素進行查詢時得到0的概率就大;但另一方面,如果哈希函數的個數少,那么位數組中的0就多。為了得到最優的哈希函數個數,我們需要根據上一小節中的錯誤率公式進行計算。 先用p和f進行計算。注意到f = exp(k ln(1 ? e<sup>?kn/m</sup>)),我們令g = k ln(1 ? e<sup>?kn/m</sup>),只要讓g取到最小,f自然也取到最小。由于p = e<sup>-kn/m</sup>,我們可以將g寫成 ![img](http://chart.apis.google.com/chart?cht=tx&chl=g=-\\frac{m}{n}\\ln(p)\\ln(1-p)) 根據對稱性法則可以很容易看出當p = 1/2,也就是k = ln2· (m/n)時,g取得最小值。在這種情況下,最小錯誤率f等于(1/2)<sup>k</sup>≈ (0.6185)<sup>m/n</sup>。另外,注意到p是位數組中某一位仍是0的概率,所以p = 1/2對應著位數組中0和1各一半。換句話說,要想保持錯誤率低,最好讓位數組有一半還空著。 需要強調的一點是,p = 1/2時錯誤率最小這個結果并不依賴于近似值p和f。同樣對于f’ = exp(k ln(1 ? (1 ? 1/m)<sup>kn</sup>)),g’ = k ln(1 ? (1 ? 1/m)<sup>kn</sup>),p’ = (1 ? 1/m)<sup>kn</sup>,我們可以將g’寫成 ![img](http://chart.apis.google.com/chart?cht=tx&chl=g'=\\frac{1}{n\\ln(1-1/m)}\\ln(p')\\ln(1-p')) 同樣根據對稱性法則可以得到當p’ = 1/2時,g’取得最小值。 #### 1.4、位數組的大小 下面我們來看看,在不超過一定錯誤率的情況下,Bloom Filter至少需要多少位才能表示全集中任意n個元素的集合。假設全集中共有u個元素,允許的最大錯誤率為?,下面我們來求位數組的位數m。 假設X為全集中任取n個元素的集合,F(X)是表示X的位數組。那么對于集合X中任意一個元素x,在s = F(X)中查詢x都能得到肯定的結果,即s能夠接受x。顯然,由于Bloom Filter引入了錯誤,s能夠接受的不僅僅是X中的元素,它還能夠? (u - n)個false positive。因此,對于一個確定的位數組來說,它能夠接受總共n + ? (u - n)個元素。在n + ? (u - n)個元素中,s真正表示的只有其中n個,所以一個確定的位數組可以表示 ![img](http://chart.apis.google.com/chart?cht=tx&chl=C_{n%2B\\epsilon(u-n)}^n) 個集合。m位的位數組共有2<sup>m</sup>個不同的組合,進而可以推出,m位的位數組可以表示 ![img](http://chart.apis.google.com/chart?cht=tx&chl=2^mC_{n%2B\\epsilon(u-n)}^n) 個集合。全集中n個元素的集合總共有 ![img](http://chart.apis.google.com/chart?cht=tx&chl=C_{u}^n) 個,因此要讓m位的位數組能夠表示所有n個元素的集合,必須有 ![img](http://chart.apis.google.com/chart?cht=tx&chl=2^mC_{n%2B\\epsilon(u-n)}^n\\geq C_{u}^n) 即: ![img](http://chart.apis.google.com/chart?cht=tx&chl=m\\geq\\log_2\\frac{C_{u}^n}{C_{n%2B\\epsilon(u-n)}^n}\\approx\\log_2\\frac{C_{u}^n}{C_{\\epsilon u}^n}\\geq\\log_2\\epsilon^{-n}=n\\log_2(1/\\epsilon)) 上式中的近似前提是n和?u相比很小,這也是實際情況中常常發生的。根據上式,我們得出結論:在錯誤率不大于?的情況下,m至少要等于n log<sub>2</sub>(1/?)才能表示任意n個元素的集合。 上一小節中我們曾算出當k = ln2· (m/n)時錯誤率f最小,這時f = (1/2)<sup>k</sup>= (1/2)<sup>mln2 / n</sup>。現在令f≤?,可以推出 ![img](http://chart.apis.google.com/chart?cht=tx&chl=m\\geq n\\frac{\\log_2(1/\\epsilon)}{\\ln 2}=n\\log_2\\log_2(1/\\epsilon)) 這個結果比前面我們算得的下界n log<sub>2</sub>(1/?)大了log<sub>2</sub>e≈ 1.44倍。這說明在哈希函數的個數取到最優時,要讓錯誤率不超過?,m至少需要取到最小值的1.44倍。 ## 問題實例 **1、給你A,B兩個文件,各存放50億條URL,每條URL占用64字節,內存限制是4G,讓你找出A,B文件共同的URL。如果是三個乃至n個文件呢?** **分析**:如果允許有一定的錯誤率,可以使用Bloom filter,4G內存大概可以表示340億bit。將其中一個文件中的url使用Bloom filter映射為這340億bit,然后挨個讀取另外一個文件的url,檢查是否與Bloom filter,如果是,那么該url應該是共同的url(注意會有一定的錯誤率)。”
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看