数据科学与算法-流算法补充

流算法补充

Queries over a sliding window

在第五章流算法中,我们讲了一些数据挖掘算法:Basic Count Sketch,Count Sketch 和 Count-min Sketch。当时我们提了一嘴滑动窗口模型,但没有细讲。现在我们来对这个数据流模型做一个补充

比如说举一个Amazon的例子,数据流是亚马逊上的订单,数据流的值是0-1,其中,0代表数据流不包含某个商品,1代表数据流包含某个商品,我们希望统计在过去的n笔订单中,有多少订单包含商品 X(统计1的个数)

朴素方法

要计算数据流中过去 k 个bits 有多少个1(k<窗口大小N),一个朴素的想法是:维持一个计数器

每当有一个新的bit进来,就需要抛弃一个bit

  • 如果进来或抛弃的bit 是 0,那么什么都不用做
  • 如果进来的bit 是1,那么计数器+1
  • 如果进来的bit 是0,那么计数器-1

这个算法的空间复杂度是$O(n)$,因为我们要时刻保持窗口中的数据;时间复杂度为$(O1)$

那么,如果N 等于 1 billion 会怎么样?我们肯定不能将其全部保存下来,因此我们可以采用一个近似算法。

尝试1

我们尝试维护两个计数器:

S: 维护数据流中的1的个数

Z: 维护数据流中的0的个数

因此我们可以用这两个计数器的值,结合窗口大小去估算窗口内1的数值:$ = N\cdot \frac{S}{S+Z} $

但是这样又不对,因为采用这种方法,随便你窗口化到哪,对1的个数的估算都是不会变的。也就是说,加入之前数据流 1和0的比值为0.8:0.2,那么相当于假设之后来的数字也是0.8:0.2,但现实生活中事件发生的概率是不停变化的,因此是不可行的。

DGIM 算法

因此我们提出了一种更高效的解决方法:DGIM算法

在DGIM算法中,我们对于一个长度为N的数据流,我们存储 $O(\log^2 N)$ 个 bits, $O(\log_2(N))$个桶 ,相当于一个亚线性的算法,而且我们要得目标的估计偏差不能超过 50%,也就是说,假设1的出现次数是100,那么我们的估计必须落在 50~150之间

首先假设对于二进制流,其中每个位可以用一个时间戳(timestamp)标志该位进入流的时间(对于大小为N的滑动窗口,该时间戳可以用O(logN)位表示)。

DGIM算法利用桶(bucket)对滑动窗口进行划分,每个桶保存以下信息:

  • 桶的最右边位即最后进入流的位的时间戳
  • 桶的大小,即桶中1的个数,该数目位2的幂。

    对于以上信息,保存时间戳需要logN的空间,保存桶的大小需要 logN 的空间。

使用桶对滑动窗口进行划分时遵循以下5条规则:

  • 桶最右边的位必须是1;
  • 1个位最多属于1个桶;
  • 每种大小的桶有1个或者两个(从1到最大的桶的大小);
  • 每个桶的大小是2的幂;
  • 桶的大小从右到左非降序排列;

DGIM算法中数据结构的更新:

  • 每一个新的位进入滑动窗口后,最左边一个位从窗口中移出(同时从桶中移出);如果最左边的桶的时间戳是当前时间戳减去N(也就是说桶里已经没有处于窗口中的位),则放弃这个桶;
  • 对于新加入的位,如果其为0,则无操作;否则建立一个包含新加入位的大小为1的桶;
  • 由于新增一个大小为1的桶而出现3个桶大小为1,则合并最左边的两个桶为一个大小为2的桶;合并之后可能出现3个大小为2的桶,则合并最左边两个大小为2的桶得到一个大小为4的桶……依次类推直到到达最左边的桶。

我们用一个直观的例子来展现:

  • 这是我们的初始数据流:

我们看到现在一共有长度为1的桶2个;长度为2的桶1个;长度为4的桶2个;长度为8的桶2个; 长度为16的桶1个,但是一部分在滑动窗口外,因此显示不出

  • 当到达了一个新的 1 ,如下图

我们发现现在长度为1的桶有3个,超出了2个,因此要向上合并

  • 当到达了三个数据 101

这时候,我们发现,合并了两个长度为1的桶,有3个长度为2的桶;合并了两个长度为2的桶,就有3个长度为4的桶;合并了两个长度为4的桶,有三个长度为8的桶。

最终,我们得到下图:

估计

最后,我们该怎么利用计数桶去怎么去估计1的个数?

  1. 我们可以叠加滑动窗口中的桶的大小,除了最后一个桶,因为最后一个桶有一部分已经滑出窗口外了
  2. 因此,我们可以近似地认为最后这个桶(也是最大的桶)的大小变为原来的$\frac{1}{2}$ ,并加到结果中去

用上面那个例子来估计,滑动窗口中,对1的个数的估计为:1+2+4+8+16+16/2 = 39个

因为一共有 $O(logn)$ 个桶,因此算法的时间复杂度也是 $O(\log n)$

精度证明

那么为什么DIGM算法,它的估算误差一定是小于50%的呢?

我们假设最后的桶的大小是 $2^r$ ,那么我们在加完前面的桶之后,最后要加上的size = $2^{r-1}$

如果这个桶没滑出去,刚好在窗口末尾停下了,那么我们就相当于少了了 $2^{r-1}$

如果这个桶基本全滑出去了,在窗口内可能只留了1个数字,那么我们就相当于多了$2^{r-1}$

但是,我们把之前的窗口全加起来: $1+2+4\cdots+2^{r-1} = 2^{r}-1$ ,他肯定是大于 等于$2^{r-1}$ 的,因此这个误差$2^{r-1}$ 肯定是小于50%的。

Extension

现在,给出一个可以进一步削弱误差的方法。

除了第一个和最后一个桶之外,其余的桶,可以将数量维持在:r-1 个或者 r 个, (r > 2)

这时候,这个算法的空间复杂度会变成 $O(r\log n)$ 但是误差率会从 50% 变成 $O(\frac{1}{r})$

此外,除了用来技术0.1,还可以用来维持一个平均值:

但是,这个算法只能进行一些简单的功能计算,要求桶内的值必须有可加性,因此推广性比较差

Counting Distinct Elements

给定一个数据流,我们来统计这个数据流中一共出现过多少不同的元素。

比如说,现在有一个集合,然后过来一个数据流,我们要统计多少这个集合的元素在这个数据流中出现了,多少没有出现。

还有其他应用场景:

  • 一个网页中出现了多少个不一样的词,词典是固定的,但词的分布是不一样的
  • 一周之内,用户总共访问了多少个不同的网站

一个很简单的方法就是:维护一个哈希表,然后过来一个数据我们映射一个数据,最后看哈希表中有哪些数据。但问题也是类似的,哈希表的大小事$O(n)$ 级别的,当数据流非常大的时候,这个哈希表是很难维护的。

因此,我们要考虑一种新的数据流算法

Flajolet-Martin Approach

FM 算法设计了一种空间复杂度为$O(\log_2(N))$ 的算法

在这个算法中,对于长度为N的数据流,我们将其映射到 长度为$\log_2(N)$ 的哈希表中。

举例来说,给定序列{e1, e2, e3, e2},独立元素数目N = 3。这里哈希数组的长度为$\log_2(4) = 2$

假设给定哈希函数H(e),有:

H(e1) = 00,TailZero(H(e1)) = 0

H(e2) = 01,TailZero(H(e2)) = 0

H(e3) = 10 ,TailZero(H(e3)) =1

第1步,将Max初始化为0;

第2步,对于序列中第1项e1,计算TailZero(H(e1)) = 0

第3步,对于序列中第2项e2,计算TailZero(H(e2)) = 0

第4步,对于序列中第3项e3,计算TailZero(H(e3)) = 1> Max, 更新Max;

第5步,对于序列中第4项e2,计算TailZero(H(e2)) =0

第6步,估计独立元素数目为 $\hat N = 2^{\max} = 2^1 = 2$。

在这个简单例子中,实际值 $N = 3$,估计值$ \hat N =2$

在实际应用中,为了减小误差,提高精度,我们通常采用一系列的哈希函数$H_1(e), H_2(e), H_3(e)$,计算一系列的Max值$\max_1,\max_2,\max_3$,从而估算一系列的估计值$2^{\max_1}, 2^{\max_2}, 2^{\max_3}$,最后进行综合得到最终的估计值。具体做法是:首先设计A*B个互不相同的哈希函数,分成A组,每组B个哈希函数;然后利用每组中的B个哈希函数计算出B个估计值;接着求出B个估计值的算术平均数为该组的估计值;最后选取各组的估计值的中位数作为最终的估计值。

举例来说,对于序列S,使用3*4 = 12个互不相同的哈希函数H(e),分成3组,每组4个哈希函数,使用12个H(e)估算出12个估计值:

Computing Moments

首先给出Moments 的概念

假设数据流是由一些数字构成的,$m_i$ 代表元素i 在流中出现的次数,那么

$k^{th}$ Moment 就是:

刚才我们做的 FM 算法,就是$k^0$ moment

$k^0$ moment: 不同元素的数量

$k^1$ moment: 元素数量的计算,也就是数据流的长度N

$k^2$ moment = suprise number S : 衡量分布的不均匀程度

这里重点考虑 $k^2$ moment

比如说数据流A、B的长度为100,一共出现了11个不同的元素

数据流A各个元素的计数:10,9,9,9 ,9,9,9, 9,9,9,9 那么 $k^2 $ moment = 910

数据流B各个元素的计数:90,1,1,1,1,1,1,1,1,1,1 那么 $k^2 $ moment = 8110

AMS Method

AMS 方法可以对所有moment的值进行一个无偏估计,这里就只针对 $k^2$ moment

我们对于一个变量 $X$

  • 用 $X.{el}$
  • 用 $X.val$

Counting Itemsets

-------------本文结束,感谢您的阅读-------------