LogLogCounting 基数估计算法

介绍

基数估计算法(Cardinality Estimation Algorithm)是基于概率统计理论的估算给定数据集中不重复元素基数的算法。
它是一种基于概率统计理论所设计的概率算法,克服了精确基数计数算法的诸多弊端(如内存需求过大或难以合并等),同时可以通过一定手段将误差控制在所要求的范围内。

什么是基数?

基数指的是一个集合(这里的集合可以包含重复元素,不是集合论中定义的集合)中不同元素的个数,例如集合{1, 2, 3, 3, 4, 5, 5, 6, 6, 6}有9个元素,但是其中不重复的元素只有 1、 2、 3、 4、 5、 6,所以它的基数是6。如果一个集合是有限集,则其基数是一个自然数。

应用场景

一个网站中有10个链接,我们需要统计这10个链接分别被多少个独立访客点击过,即每个链接的UV数量。

基数统计算法

数据的收集和存储不是这篇文章的重点,假设我们已经拿到了数据:10个链接的用户访问数据集合,我们如何获取这些集合的基数呢?

传统的方法

  • 基于bitmap的实现
    • 由于每个用户对于每个链接只有 访问/未访问 这两种状态, 所以我们将每一个独立用户映射到一个bit位上,这样可以使用一串bit数组来表示一个链接的访问基数,计算访问基数的时候只需要计算bit数组中1的数量就可以了。
    • 优点
      • 可以精确地计算出每个链接的UV数
      • 可以高效地进行合并,例如需要计算多个链接的UV数之和,只需要按位进行或运算。
    • 问题
      • 对于每一个链接,都需要维护一个bit数组,这个数组的大小与集合中的元素个数无关,而是与基数的上限有关,计算上限为1亿的基数,需要12.5M字节的bitmap。最大的问题是即使一个链接仅仅只有一个UV,也要为其分配12.5M字节大小的数组,这样会造成巨大的浪费。

LogLogCounting

  • LogLogCounting

    • LogLog代表空间复杂度,这种算法的空间复杂度仅有O(log2(log2(Nmax))),可以通过KB级内存估计数亿级别的基数
  • 均匀随机化

    • 这个算法需要选取一个哈希函数H应用于所有元素,然后对哈希值进行基数估计。H必须满足如下条件:
      1. H的结果具有很好的均匀性,也就是说无论原始集合元素的值分布如何,其哈希结果的值几乎服从均匀分布
      2. H的碰撞几乎可以忽略不计。也就是说我们认为对于不同的原始值,其哈希结果相同的概率非常小以至于可以忽略不计
      3. H的哈希结果是固定长度的
  • 基本思想(伯努利试验以及其推论)

    • 伯努利试验:一次实验的结果只有发生和不发生两种,重复做这个实验,直到结果发生为止,记录下实验的次数。
    • 步骤
      1. 设a为待估集合中的一个元素,通过计算a的哈希值,可以得到一个固定长度的比特串(a的二进制表示),设H哈希后的结果长度为L比特,我们将这L个比特位从左到右分别编号为1、2、…、L。

      2. 由于a是从服从均匀分布的空间中随机抽取的一个样本,所以a的每个比特位为0或者1的概率都是1/2,且相互独立。

      3. ρ(a) 为a的比特串中第一个'1'出现的位置, 则1 ≤ ρ(a) ≤ L成立(忽略比特串全为0的情况(概率为1/2^L))

      4. 遍历集合中所有元素的比特串,取ρmax为所有ρ(a)的最大值

    此时我们可以将2^ρmax作为基数的一个粗糙估计,也就是说这个集合的基数是2的ρmax次方

  • 为什么是2^ρmax?

    • 由于比特串每个比特都独立且服从0-1分布,因此从左到右扫描上述某个比特串寻找第一个“1”的过程从统计学角度看是一个伯努利过程。例如,可以等价看作不断投掷一个硬币(每次投掷正反面概率皆为0.5),直到得到一个正面的过程。在一次这样的过程中,投掷一次就得到正面的概率为1/2,投掷两次得到正面的概率是1/2^2,…,投掷k次才得到第一个正面的概率为1/ 2^k。

    • 以抛硬币(正反面概率相同)为例,连续抛硬币直到出现正面时停止,记录下抛掷次数(这个过程称之为伯努利过程),n次伯努利过程会得到n个首次出现正面的抛掷次数,其中最大抛掷次数为k,可以通过最大抛掷次数估算出总抛掷次数:n = 2^k

    • 问题

      1. 进行n次伯努利过程,所有投掷次数都不大于k的概率是多少?
        • 在一次伯努利过程中,投掷次数大于k的概率为1/2^k,即连续掷出k个反面的概率。因此,在一次过程中投掷次数不大于k的概率为1−1/2^k。n次伯努利过程投掷次数均不大于k的概率为:(1−1/2^k)^n
      2. 进行n次伯努利过程,至少有一次投掷次数等于k的概率是多少?
        • 答案显然是 1-(1-1/2^(k-1))^n
    • 可以看出,当n≪2^k 时, Pn(X≥k)的概率几乎为0,同时,当n≫2^k 时,Pn(X≤k)的概率也几乎为0。即:当伯努利过程次数远远小于2^k 时,至少有一次过程投掷次数等于k的概率几乎为0;当伯努利过程次数远远大于2^k时,没有一次过程投掷次数大于k的概率也几乎为0。

    • 结论:
      设一个集合的基数为n,ρmax为所有元素中首个“1”的位置最大的那个元素的“1”的位置,如果n远远小于2^ρmax,则我们得到ρmax为当前值的概率几乎为0(它应该更小),同样的,如果n远远大于2^ρmax,则我们得到ρmax为当前值的概率也几乎为0(它应该更大),因此2ρmax可以作为基数n的一个粗糙估计。

  • 分桶平均

    • LogLog Counting为了避免偶然性,会先进行分桶,每次抛硬币先随机分配到其中一个桶,每个桶保存最大抛掷次数,最后通过所有桶最大抛掷次数的均值计算,但是在抛掷次数小时误差还是会比较大。具体来说,就是将哈希空间平均分成m份,每份称之为一个桶(bucket)。对于每一个元素,其哈希值的前k比特作为桶编号,其中2^k=m,而后L-k个比特作为真正用于基数估计的比特串。桶编号相同的元素被分配到同一个桶,在进行基数估计时,首先计算每个桶内元素最大的第一个“1”的位置,设为M[i],然后对这m个值取平均后再进行估计
  • 偏差修正

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容