zoukankan      html  css  js  c++  java
  • Bloom Filter:海量数据的HashSet

    Bloom Filter一般用于数据的去重计算,近似于HashSet的功能;但是不同于Bitmap(用于精确计算),其为一种估算的数据结构,存在误判(false positive)的情况。

    1. 基本原理

    Bloom Filter能高效地表征数据集合(S = lbrace x_1 ,x_2 ,...,x_n brace),判断某个数据是否属于这个集合。其基本思想如下:用长度为(m)的位数组(A)来存储集合信息,同时是有(k)个独立的hash函数(h_i(1le i le k))将数据映射到位数组空间。具体流程如下:

    1. 将长度为(m)的位数组全置为0;
    2. 对于数据(x in S),依次计算其(k)个hash函数值(h_i(x)=w,且1le i le k, 1 le w le m),将位数组中的第(a)位bit置为1,即A[w]=1.

    当查询数据(y)是否属于集合(S)时,计算其(k)个hash函数值,如果(h_i(y))对应的位数组均为1,则数据(y)属于集合(S);反之,则不属于。

    2. 相关计算

    在上述判断中,可能存在误判(false positive, FP),比如某数的(k)个hash函数值可能属于集合(S)中某几个数(k)个hash函数值组成的集合。显然,误判率跟集合大小(n)、位数组大小(m)、hash函数的个数(k)有关;在其他条件不变的情况下,若(n)越大((m)越小,或(k)越多),则误判率越高。误判率估算公式如下:

    [P_{fp} approx (1-e^{-kn/m})^k ]

    在实际的场景中,常常是已知集合大小(n),预设误判率(P_{fp}),需要计算位数组大小(m)、hash函数的个数(k)。通过一系列的数学推导,可得到如下公式:

    [m= - frac{nln P_{fp}}{(ln 2)^2} ]

    [k=frac{m}{n}ln 2 ]

    详细的数学推导可参看相关文档。

    3. 实战

    Bloom Filter的Java实现有Guava、stream-lib,Scala实现有breezebloom-filter-scala。采用breeze库的Distinct Count实现如下:

    import breeze.util.BloomFilter
    
    val bf = BloomFilter.optimallySized[Int](5, 0.01)
    val arr = Array(1, 3, 4, 5, 1, 2, 6, 3, 1)
    var cnt = 0
    arr.foreach { t =>
      bf.contains(t) match {
        case false => cnt += 1; bf.+=(t)
        case _ =>
      }
    }
    println(arr.distinct.length) // 6
    println(cnt) // 6
    

    从上面的Scala代码中,不难发现:在Distinct Count计算过程中,需要定义一个global变量,逐一用于对每个不属于集合元素进行计算。显然,在分布式计算中,这种方法不太适用;因为global变量没法做到实时的传递更新。因此,另一种估算算法HyperLogLog,拥有优秀的可加性、易于并行化,在大数据的场景下应用广泛——Spark、Kylin中的近似Distinct Count便是基于此。

    4. 参考资料

    [1] Broder, Andrei, and Michael Mitzenmacher. "Network Applications of Bloom Filters: A Survey." Internet Mathematics 1.4 (2011): 485-509.
    [2] 张俊林, 《大数据日知录》.

  • 相关阅读:
    动态规划01背包
    动态规划矩阵连乘
    分治法归并排序
    动态规划最长公共子序列
    贪心算法活动安排
    分治法二分查找
    vue 可拖拽可缩放 vuedraggableresizable 组件常用总结
    rifilter in python discussed in 3delight
    3delight linear work flow
    pixar stereo rendering doc
  • 原文地址:https://www.cnblogs.com/en-heng/p/5881997.html
Copyright © 2011-2022 走看看