Fast Algorithm for GK Summary算法


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 算法如下:

// 直接结束当前阶段,生成summary
if ( SC != empty; )
{      
    s_all = s0;
    for ( i = 1; i <= L; i++ )
    {
         s_all = Merge(s_all, si);
    }             
    Sk = compress( s_all, ε/2 );
}
// merge所有的阶段的summary
S = S0
for ( 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章