Fast Algorithm for GK Summary算法

来源:互联网 发布:二级域名做优化 编辑:程序博客网 时间:2024/04/28 06:32

  • 前言
  • 算法思路
    • 1 数据量固定的算法
    • 2 数据量固定的算法复杂度
    • 3 流式数据算法
    • 4 流式算法复杂度分析
  • 参考文献


0.前言

  本文主要介绍Zhang and Wang利用GK Summary的Merge与Prune操作来构建新的ϵapproximate quantile summary,提出了A Fast quantile summary algorithm,速度非常快,注意本文的Compress操作即为Prune操作,因为论文使用该名词,保持一致。本文仅提取出关键内容加入笔者的个人理解,有错误还望谅解与告知。

1.算法思路

  Zhang and Wang在论文先描述:1)数据量固定的算法,即已知数据量N。2)通过数据流分阶段,每个阶段数据量固定,因此可以将算法扩展到流式数据库场景,而不依赖先验的数据量N

1.1 数据量固定的算法

  首先考虑:数据量固定场景,论文提出多层quantile summary结构:

S={s0,s1,...,sL}

  其中si为第i级的quantile summaryb=log(ϵN)/ϵ,为每级summary的最大个数,算法流程如下:

for ( i = i; i ≤ N; i++ ){    insert vi into s0;                 //新进数据直接插入s0    if ( |s0| < b )                    //s0没满,则继续插入        contiune;     sort s0;                           //s0满了,则排序并执行compress操作    sc = compress(s0, 1/b);            //生成sc,1/b为prune增加误差,对应生成b/2个元素,s0误差为0    s0 = ∅;    for ( k = 1; k <= L; k++ )         {        if ( |sk| == 0 )               //sk是否为空        {            sk = sc;                   //为空,则加入sc            break;        } else {            tmp = merge(sk, sc);       //否则,sc与sk进行merge,此时对应误差max(ϵk, 1/b)            sc = compress(tmp, 1/b);   //ϵk为sk的误差,继续compress,max(ϵk, b/2) + 1/b            sk = ∅                     //sk置空,可以归纳出,sk存在summary时,误差为k*(1/b)        }                              //上层误差比下层大。     }}

  方便理解,对应图示如下:


这里写图片描述

  证明:对于第k层,出现满的状态,需要数据量为N/(2k×b)个数据。因此,L层的summaryL层最多只能1次为满,则:
N/(2L×b)12LN/bLlog(N/b)          (b=log(ϵN)/ϵ)=log(ϵN/log(ϵN))=log(ϵN)log(log(ϵN))<log(ϵN)

  对于第k层,对应误差为ϵk=k/b, 最大误差是L层对应ϵL:

sL=L/log(ϵN)/ϵ<log(ϵN)/(log(ϵN)/ϵ)<ϵ

  最终查询时,会将所有层的summary merge一起:

S=Merge(s0,s1,...,sk)

  S误差约束:

ϵ=max(ϵ0,ϵ1,...,ϵk)=sL<ϵ

  上述可见,b设置极其巧妙。

1.2 数据量固定的算法复杂度

  论文给出算法的空间复杂度为:

O(bL)=log(ϵN)/ϵ×log(N/b)log2(ϵN)/ϵ

  GK Summary算法的空间复杂度O(log(ϵN)/ϵ), 可见Fast的算法复杂度更优。

  论文给出平均每个元素summary更新时间复杂度为:O(log(log(ϵN)/ϵ)),几乎近似于常熟复杂度。时间复杂度等价于GK Summary最好情况的复杂度,而GK Summary最差情况的复杂度为O(log(ϵN)/ϵ)时间复杂度证明:

  算法主要是s0执行compress,从无序数据到有序的summary,因此s0只需要排序+compress,每次排序复杂度是blogb, compressb/2, 总共需要执行N/b次。而对于其他层(i>0),因为merge下层summary已经是有序,因此对于第i层来说需要简单merge+compressmerge复杂度为2b, compress复杂度为b,需要执行N/(2ib),因此计算时间为:

Nlogb+N/2+i=1LN2ib3b=O(Nlog(log(ϵN)/ϵ))

1.3 流式数据算法

  现在考虑流式数据场景,论文将流式数据进行分阶段进行构建summary,将流按照对于大小来分段。阶段1为0~1/ϵ数据,阶段2为1/ϵ~3/ϵ数据,阶段n对应(2n11)/ϵ~(2n1)/ϵ数据。数据流式不断增加,对应n也不断变大,每个阶段,数据长度是固定的,阶段i,数据长度为定值2i1/ϵ。因此,可以套用上述讲到的数据量固定算法,具体思路是将每个阶段生成的误差边界都保持在ϵ,但是却是通过Compress(Merge(s0,s1,...sL),ϵ/2)(不同于直接限定误差ϵ,只需要进行merge,compress操作能减少summary个数),每个阶段生成2/ϵ+1summary,最终merge每个阶段生成的summary,情况如下图所示。


这里写图片描述

  算法流程如下:

  S = ∅;SC = ∅; k = 0; N = 1/ε; //初始化值  while ( not EOS )  {      e = next element in stream; //流式系统新数据     n++;                    SC = Update(e, SC, ε/2);  // 调用上述固定长度的fast quantile算法,生成对应summary     if ( n == N)              // 第i阶段结束     {        // 下面过程生成第i阶段的summary SC,误差边界ε/2        s_all = s0;        for ( i = 1; i <= L; i++ )        {           s_all = Merge(s_all, si);        }        Sk = compress( s_all, ε/2);  // 将summary compress到2/ε,减少summary数        S = S ∪ Sk;                 // 合并所有阶段summary        SC = ∅;        // 重置        n = 0;        N = 2×N;     }  }

  生成最终summary算法如下:

// 直接结束当前阶段,生成summaryif ( SC != empty; ){          s_all = s0;    for ( i = 1; i <= L; i++ )    {         s_all = Merge(s_all, si);    }                 Sk = compress( s_all, ε/2 );}// merge所有的阶段的summaryS = S0for ( i = 1; i ≤ k; i++ )   S = Merge(S, Si);

1.4 流式算法复杂度分析

  论文给出空间复杂度:O(log2(ϵN)/ϵ), 时间复杂度为:O(log(log(ϵN)/ϵ)),证明:整个过程等价于最新阶段summary计算复杂度。


参考文献

  1. A fast algorithm for approximate quantiles论文: https://pdfs.semanticscholar.org/03a0/f978de91f70249dc39de75e8958c49df4583.pdf
  2. Emory大学Stream DB System课程关于A Fast Algorithm算法材料:
    http://www.mathcs.emory.edu/~cheung/Courses/584-StreamDB/Syllabus/08-Quantile/Zhang.html
  3. Emory大学Stream DB System课程关于A Fast Algorithm算法材料:
    http://www.mathcs.emory.edu/~cheung/Courses/584-StreamDB/Syllabus/08-Quantile/Zhang2.html
原创粉丝点击