基数统计:从Linear Counting到Hyper LogLog

欢迎来我的小站转转~~

应用场景

基数统计(Cardinality Counting)指计算一个数据集中不同元素的数量,在很多场景都需要这样的功能:电商场景中的独立用户(UV)数量统计、数据库中快速计算字段取值数量以优化query、计算与某个站点相关的不同链接数量等。

为实现这样的功能,最直观的方法就是使用 Set 记录每一个元素,在数量巨大的情况下,会造成大量的内存占用。以存储 2 30 2^{30} 230 (约10亿)个长度为64bit的url为例,需要占用 64 ∗ 2 30 = 64 G B 64*2^{30} = 64GB 64230=64GB 的空间。Set方案的空间占用与元素的数量成正比,空间复杂度为 O ( N ) O(N) O(N)

如果使用bitmap来存储,则需要将不同的url映射到不同的数字。即使最理想的情况下,url之间没有冲突,且从1到 2 30 2^{30} 230 都没有空闲,bitmap也需要占用 2 30 ÷ 8 = 2 27 = 128 M B 2^{30}\div 8 = 2^{27} = 128MB 230÷8=227=128MB 的空间。bitmap方案占用空间只与最大取值有关系,与元素数量无关。极端情况下,即使只有一个url,在这个例子中也需要占用128MB的空间,空间复杂度为 O ( N m a x ) O(N_{max}) O(Nmax)

以上两种方式都对基数进行精确统计,但是很多时候只需要一个大概的数量,只要误差在一定范围内即可。接下来要讨论的几种算法可以在牺牲一定精确性的情况下,大幅度降低空间占用。

Linear Counting

诞生于1990年的论文“A linear-time probabilistic counting algorithm for database applications“,相比bitmap有常数项的空间复杂度优化,但整体还是 O ( N m a x ) O(N_{max}) O(Nmax)

在这里插入图片描述

主要步骤

  1. 数据哈希:假设原始数据的基数为n,使用一组哈希空间为m的哈希函数H,将原始数据均匀分组。
  2. 分桶数据统计:构建一个长度为m的bitmap,其中每一个bit对应哈希空间的一个值。生成哈希数组的值如果存在,则把相应的bit设置为1。
  3. 数量估计:当所有值设置完成后,统计bitmap中为0的bit数为u。则估计的基数为 n ^ = − m log ⁡ u m \hat{n} = -m \log {\frac{u}{m}} n^=mlogmu

基数公式推导

记事件 A j A_j Aj 为“经过n个数字哈希之后,桶j仍然为空”,则 P ( A j ) = ( 1 − 1 m ) n P(A_j) = (1-\frac{1}{m})^n P(Aj)=(1m1)n

U n U_n Un 为经过n个数字哈希之后,仍然为空的桶数量。因为各个桶之间互相独立,所以 E ( U n ) = m ( 1 − 1 m ) n = m [ ( 1 + 1 − m ) − m ] − n m E(U_n) = m(1-\frac{1}{m})^n = m[(1+\frac{1}{-m})^{-m}]^{-\frac{n}{m}} E(Un)=m(1m1)n=m[(1+m1)m]mn

当m趋向于无穷大时, lim ⁡ m → ∞ E ( U n ) = lim ⁡ m → ∞ m [ ( 1 + 1 − m ) − m ] − n m = m e − n m \lim_{m \to \infty} E(U_n) = \lim_{m \to \infty } m[(1+\frac{1}{-m})^{-m}]^{-\frac{n}{m}} = me^{-\frac{n}{m}} limmE(Un)=limmm[(1+m1)m]mn=memn

得到 n = − m log ⁡ E ( U n ) m n = -m \log{\frac{E(U_n)}{m}} n=mlogmE(Un)

由于每个桶的取值都服从参数相同的0-1分布,所以 U n U_n Un符合二项分布。当n很大的时候,可以用正态分布逼近二项分布, U n U_n Un 的概率密度函数为:

f ( x ) = 1 σ 2 π e − ( x − μ ) 2 2 σ 2 f(x) = \frac{1}{\sigma \sqrt{2\pi}} e^{-\frac{(x-\mu)^2}{2{\sigma}^2}} f(x)=σ2π 1e2σ2(xμ)2

因此我们实际观察到的空桶数量 u u u 可以作为 E ( U n ) E(U_n) E(Un) 的无偏估计,由于 = − m log ⁡ x m = -m \log{\frac{x}{m}} =mlogmx 是可逆函数,可以把 n ^ \hat{n} n^ 作为理论 n n n 的无偏估计。

误差估计

偏差

记装载因子 t = n m t=\frac{n}{m} t=mn , 空桶比例 V n = U n m V_n = \frac{U_n}{m} Vn=mUn , 空桶数量期望 p = E ( V n ) = E ( U n ) m = e − n m = e − t p = E(V_n)=\frac{E(U_n)}{m} = e^{-\frac{n}{m}} = e^{-t} p=E(Vn)=mE(Un)=emn=et

− ln ⁡ ( V n ) = f ( V n ) -\ln(V_n) = f(V_n) ln(Vn)=f(Vn),则 n ^ = m ∗ ( − ln ⁡ u m ) = m f ( V n ) \hat{n} = m*(-\ln{\frac{u}{m}})=mf(V_n) n^=m(lnmu)=mf(Vn)

V n V_n Vn 处进行泰勒展式:

n ^ = m f ( V n ) = m ( f ( p ) + ( V n − p ) f ′ ( p ) + 1 2 ( V n − p ) 2 f ′ ′ ( p ) + 1 6 ( V n − p ) 3 f ′ ′ ′ ( p ) . . . . ) \hat{n} = mf(V_n) = m(f(p)+(V_n-p)f'(p)+\frac{1}{2}(V_n-p)^2f''(p)+\frac{1}{6}(V_n-p)^3f'''(p)....) n^=mf(Vn)=m(f(p)+(Vnp)f(p)+21(Vnp)2f(p)+61(Vnp)3f(p)....)

= m ( t − V n − p p + ( V n − p ) 2 2 p 2 − ( V n − p ) 3 3 p 3 + ( V n − p ) 4 4 p 4 . . . . ) =m(t-\frac{V_n-p}{p}+\frac{(V_n-p)^2}{2p^2}-\frac{(V_n-p)^3}{3p^3}+\frac{(V_n-p)^4}{4p^4}....) =m(tpVnp+2p2(Vnp)23p3(Vnp)3+4p4(Vnp)4....)

取前三项:

E ( n ^ ) = m t − m E ( V n − p ) p + E ( V n − p ) 2 2 p 2 E(\hat{n}) = mt-\frac{mE(V_n-p)}{p} + \frac{E(V_n-p)^2}{2p^2} E(n^)=mtpmE(Vnp)+2p2E(Vnp)2

由于 p = E ( V n ) p=E(V_n) p=E(Vn) , E ( V n ) − p = 0 E(V_n)-p=0 E(Vn)p=0

所以可以化简为
E ( n ^ ) = m t + m 2 p 2 E ( V n − p ) 2 E(\hat{n}) = mt+\frac{m}{2p^2}E(V_n-p)^2 E(n^)=mt+2p2mE(Vnp)2

其中
E ( V n − p ) 2 = V a r ( V n ) = ( 1 m ) e − t ( 1 − ( 1 + t ) e − t ) E(V_n-p)^2 = Var(V_n) = (\frac{1}{m})e^{-t}(1-(1+t)e^{-t}) E(Vnp)2=Var(Vn)=(m1)et(1(1+t)et)

V a r ( V n ) Var(V_n) Var(Vn) 通过 V a r ( X ) = E ( X 2 ) − E ( X ) 2 Var(X) = E(X^2)-E(X)^2 Var(X)=E(X2)E(X)2 得到,计算的具体过程可以见论文Appendix A。

最终 E ( n ^ ) = n + e t − t − 1 2 E(\hat{n}) = n+\frac{e^t-t-1}{2} E(n^)=n+2ett1

B i a s ( n ^ n ) = E ( n ^ n ) − 1 = e t − t − 1 2 n Bias(\frac{\hat{n}}{n}) = E(\frac{\hat{n}}{n})-1 = \frac{e^t-t-1}{2n} Bias(nn^)=E(nn^)1=2nett1

从中得到一个显然的结论:m越大,偏差越小。

标准差

取泰勒展式的前两项, n ^ = m ( t − V n − p p ) \hat{n} = m(t-\frac{V_n-p}{p}) n^=m(tpVnp)

V a r ( n ^ n ) = 1 n 2 ( m 2 p 2 V a r ( V n − p ) ) = 1 n 2 ( m 2 p 2 V a r ( V n ) ) = 1 n 2 ( m 2 p 2 1 m ) p ( 1 − ( 1 + t ) p ) = m ( e t − t − 1 ) n 2 Var(\frac{\hat{n}}{n}) = \frac{1}{n^2}(\frac{m^2}{p^2} Var(V_n-p)) =\frac{1}{n^2}(\frac{m^2}{p^2} Var(V_n)) =\frac{1}{n^2}(\frac{m^2}{p^2} \frac{1}{m})p(1-(1+t)p) = \frac{m(e^t-t-1)}{n^2} Var(nn^)=n21(p2m2Var(Vnp))=n21(p2m2Var(Vn))=n21(p2m2m1)p(1(1+t)p)=n2m(ett1)

具体过程见论文的Appendix C,得 S t d E r r o r ( n ^ n ) = m ( e t − t − 1 ) n StdError(\frac{\hat{n}}{n}) = \frac{\sqrt{m(e^t-t-1)}}{n} StdError(nn^)=nm(ett1)

其中 t = n m t=\frac{n}{m} t=mn 。对m求导得到 1 m ( e n m ( m − n ) − 1 ) \frac{1}{m}(e^{\frac{n}{m}}(m-n)-1) m1(emn(mn)1),由于m小于n,这是一个对m的递减函数,因此分桶数量越大,标准差越小。

长度m的选择

误差控制

如果我们需要将误差控制在 ϵ \epsilon ϵ 以下,即
m ( e t − t − 1 ) n = e t − t − 1 t t < ϵ \frac{\sqrt{m(e^t-t-1)}}{n} = \frac{\sqrt{\frac{e^t-t-1}{t}}}{t} \lt \epsilon nm(ett1) =ttett1 <ϵ
得到m的最小数量为
m > e t − t − 1 ( ϵ t ) 2 m \gt \frac{e^t-t-1}{(\epsilon t)^2} m>(ϵt)2ett1

满桶控制

在这里插入图片描述

注意到,如果每个桶的都置为1,即 u = 0 u=0 u=0 ,那么 n ^ = − m log ⁡ u m \hat{n} = -m \log {\frac{u}{m}} n^=mlogmu 就会趋向于无穷大,失去意义。但只要m<n,就总有概率导致 u = 0 u=0 u=0,我们追求的是这个概率足够小

n → + ∞ n \to +\infty n+,则 U n U_n Un 的二项分布可近似为正态分布

可以通过让 U n U_n Un 的期望相比0的偏移大于若干倍的 U n U_n Un 标准差来控制:
E ( U n ) − a × S t d D e v ( U n ) > 0 E(U_n)-a\times StdDev(U_n) >0 E(Un)a×StdDev(Un)>0
代入 E ( U n ) = m e − t E(U_n)=me^{-t} E(Un)=met S t d D e v ( U n ) = ( m e − t ( 1 − ( 1 + t ) e − t ) ) 1 2 StdDev(U_n)=(me^{-t}(1-(1+t)e^{-t}))^{\frac{1}{2}} StdDev(Un)=(met(1(1+t)et))21,得到

m > a 2 ( e t − t − 1 ) m>a^2(e^t-t-1) m>a2(ett1)

结合两个限制条件

结合误差控制和满桶控制,最终m在期望误差内的最小长度为:
m > β ( e t − t − 1 ) , β = m a x ( a 2 , 1 ( ϵ t ) 2 ) m>\beta (e^t-t-1), \quad \beta=max(a^2, \frac{1}{(\epsilon t)^2}) m>β(ett1),β=max(a2,(ϵt)21)

确定a

u满足二项分布,当n非常大而落进一个桶的概率 p = 1 m p=\frac{1}{m} p=m1 非常小时,可以用泊松分布进行近似
lim ⁡ n , m → ∞ P r ( U n = k ) = λ k k ! e − λ \lim_{n,m \to \infty}Pr(U_n=k) =\frac{\lambda^k}{k!}e^{-\lambda} n,mlimPr(Un=k)=k!λkeλ
因此,满桶的概率为
P r ( U n = 0 ) = e − λ Pr(U_n=0)=e^{-\lambda} Pr(Un=0)=eλ
如果要满桶的概率小于1%,只要 e − λ < 0.01 e^{-\lambda}<0.01 eλ<0.01,得到 λ > 5 \lambda>5 λ>5,所以只要 U n U_n Un 的期望与0偏离为 5 \sqrt{5} 5 即可保证满桶的概率小于 1%。同理,可以将概率设置为其他值来求出对应的a,满桶概率越小需要的a越大。

空间复杂度

a = 5 a=\sqrt{5} a=5 的情况下,作者对不同规模n下m的最小长度进行了计算,随着m和n的增大,m大约为n的十分之一。因此LC所需要的空间只有传统的bitmap直接映射方法的1/10,但整体空间复杂度仍为 O ( N m a x ) O(N_{max}) O(Nmax)。结果如下表

在这里插入图片描述

仍以 n = 2 30 n=2^{30} n=230 为例,通过计算机求解得到 ϵ = 0.01 \epsilon=0.01 ϵ=0.01时, m = 75402422 m=75402422 m=75402422,因此空间占用为 m / 8 / 1024 / 1024 = 9 m/8/1024/1024=9 m/8/1024/1024=9 MB,约为bitmap方案的 9 M B / 128 M B = 1 14 9MB/128MB = \frac{1}{14} 9MB/128MB=141 ,与表中的比例数量级相符。

并集与交集

只要哈希函数和m相同,Linear Counting支持对多个记录进行合并计算。
如果要计算两个集合的并集 s e t _ s i z e ( R 1 ∪ R 2 ) set\_size(R_1 \cup R_2) set_size(R1R2),可以简单进行 OR 运算得到新的bitmap,然后计算出估计结果。
如果要计算两个集合的交集,可以通过两集合和并集间接算出来: s e t _ s i z e ( R 1 ∩ R 2 ) = s e t _ s i z e ( R 1 ) + s e t _ s i z e ( R 2 ) − s e t _ s i z e ( R 1 ∪ R 2 ) set\_size(R_1 \cap R_2) = set\_size(R_1)+set\_size(R_2)-set\_size(R_1 \cup R_2) set_size(R1R2)=set_size(R1)+set_size(R2)set_size(R1R2)

在这里插入图片描述

问题

Linear Counting在n过大时,会导致bitmap满桶,此时误差就会变为无穷大。

LogLog Counting

Linear Counting虽然有了常数级的优化,但空间复杂度仍然是 O ( N ) O(N) O(N) 级别,而LogLog Counting却如其名只有 O ( log ⁡ 2 ( log ⁡ 2 ( N ) ) O(\log_2(\log_2 (N)) O(log2(log2(N)) 的空间复杂度。目前在处理大数据的基数问题时,采用的方法基本都是LogLog Counting的几个变种。

主要步骤

与Linear Counting一样,LogLog Counting 需要选取一个哈希函数H应用于所有元素,然后对哈希值进行基数估计。H必须满足如下条件:

1、具有很好的均匀性:无论原始值如何分布,其哈希结果的值都服从均匀分布(完全服从均匀分布是不可能的,但是很多哈希函数可以生成几乎服从均匀分布的结果)。

2、H的碰撞几乎可以忽略不计:对于不同的原始值,其哈希结果相同的概率非常小。

3、H的哈希结果是固定长度的。

在这里插入图片描述

设a是经过H哈希后的一个值,长度固定为L。因为经过H的哈希结果服从均匀分布,所以a中每个比特的取值为1的概率都是0.5,且相互独立。记 ρ ( a ) \rho (a) ρ(a) 为a的比特串中第一个“1”出现的位置, ρ m a x \rho_{max} ρmax 为所有元素哈希后 ρ ( a ) \rho (a) ρ(a) 的最大值。

则对于总量的估计为 n ^ = 2 ρ m a x \hat{n} = 2^{\rho_{max}} n^=2ρmax

粗糙估计

为什么可以这样估计呢?

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

现在如果进行n次伯努利过程,所有投掷次数都不大于k的概率和至少有一次投掷次数大于k的概率分别为:

P n ( X ≤ k ) = ( 1 − 1 2 k ) n P_n(X \le k) = (1-\frac{1}{2^k})^n Pn(Xk)=(12k1)n

P n ( X ≥ k ) = 1 − ( 1 − 1 2 k ) n P_n(X \ge k) = 1-(1-\frac{1}{2^k})^n Pn(Xk)=1(12k1)n

由此可见,当 n ≪ 2 k n \ll 2^k n2k 时, P n ( X ≥ k ) P_n(X \ge k) Pn(Xk) 几乎为零; n ≫ 2 k n \gg 2^k n2k 时, P n ( X ≤ k ) P_n(X \le k) Pn(Xk) 也几乎为零。从这里就可以衍生出一个结论:如果对n个元素进行哈希后,得到 ρ m a x \rho_max ρmax ,则 P ( 2 ρ ≪ n ) P(2^{\rho} \ll n) P(2ρn) P ( 2 ρ ≫ n ) P(2^{\rho} \gg n) P(2ρn) 都几乎为零, 2 ρ 2^{\rho} 2ρ 可以作为n的一个粗糙估计。

分桶平均

但是上述的估计实在太粗糙了,因此 LogLog Counting使用分桶平均的方式,根据前k个bit,将哈希空间平分为 m = 2 k m=2^k m=2k 份,每个桶都单独维护一个 ρ m a x \rho_{max} ρmax,形成一个数组 M M M。在进行哈希的时候,根据一个元素的前k个bit确定桶编号i,剩余的bit按照上述的步骤更新 M [ i ] M[i] M[i] ρ m a x \rho_{max} ρmax,最终估计时取所有桶的平均值再进行估计。

n ^ = 2 Σ M [ i ] m \hat{n} = 2^{\frac{\Sigma{M[i]}}{m}} n^=2mΣM[i]

在这里插入图片描述

误差修正

分桶平均只是减少了误差,但是仍然基于粗糙的估计,因此论文对其进行了修正以达到无偏估计。

这部分需要大量的数学分析,只提一下分析的框架:

P n ( X = k ) = ( ( 1 − 1 2 k ) n ) − ( ( 1 − 1 2 k − 1 ) n ) P_n(X = k) = ((1-\frac{1}{2^k})^n)-((1-\frac{1}{2^{k-1}})^n) Pn(X=k)=((12k1)n)((12k11)n)

构建指数生成函数,通过poissonization得到估计量的 P o i s s o n Poisson Poisson 期望和方差后,通过de-poissonization 得到一个渐近无偏估计量:

n ^ = α m 2 1 m Σ M [ i ] \hat{n} = \alpha_m2^{\frac{1}{m}\Sigma{M[i]}} n^=αm2m1ΣM[i]

其中

α m = ( Γ ( − 1 m ) 1 − 2 1 m log ⁡ 2 ) − m \alpha_m = (\Gamma (-\frac{1}{m})\frac{1-2^{\frac{1}{m}}}{\log 2})^{-m} αm=(Γ(m1)log212m1)m

Γ ( s ) = 1 s ∫ 0 ∞ e − t t s   d t \Gamma(s) = \frac{1}{s} \int_{0}^{\infty}{e^{-t}t^s}\,dt Γ(s)=s10ettsdt

误差分析

不加证明得给出结论:

m > 64 m \gt 64 m>64 S t d E r r o r ( n ^ n ) ≈ 1.3 m StdError(\frac{\hat{n}}{n}) \approx \frac{1.3}{\sqrt{m}} StdError(nn^)m 1.3

如果要将误差控制在 ϵ \epsilon ϵ 之内,则

m > ( 1.30 ϵ ) 2 m \gt (\frac{1.30}{\epsilon})^2 m>(ϵ1.30)2

空间复杂度

内存使用与m的大小及哈希值长度有关,如果统计的基数大小为n,则 ρ m a x ≥ O ( log ⁡ 2 n m ) \rho_{max} \ge O(\log_2{\frac{n}{m}}) ρmaxO(log2mn),对应保存 M M M 的空间为 $O(m \times \log_2{\rho_{max}}) $,在m固定时,空间复杂度为 O ( l o g 2 ( l o g 2 n ) ) O(log_2(log_2n)) O(log2(log2n))
假设哈希后长度为64bit,则 ρ m a x ≤ 64 \rho_{max} \le 64 ρmax64,因此每个桶需要 log ⁡ 2 64 = 6 \log_2{64} = 6 log264=6 bit的空间来存储 ρ m a x \rho_{max} ρmax,分成m个桶即 6 × m 8 \frac{6\times m}{8} 86×m 字节。当分桶数m为1024时,误差为 1.3 ÷ 1024 ≈ 4 % 1.3 \div \sqrt{1024} \approx 4\% 1.3÷1024 4%,需要的字节数就是 6 × 1024 ÷ 8 = 768 B 6\times 1024 \div 8 = 768B 6×1024÷8=768B ,比起Linear Counting的 9MB 有了5个数量级的下降。

并集与交集

LogLog Counting也支持计算两个集合的并集基数,区别在于LogLog Counting以桶为单位,而Linear Counting以bit为单位。由于LogLog Counting只需要记录桶的 ρ m a x \rho_{max} ρmax,所以合并的时候取相同桶编号中较大的 ρ m a x \rho_{max} ρmax即可。

问题

LogLog Counting比Linear Counting的节约了指数级的空间,但是它误差控制在 1.3 m \frac{1.3}{\sqrt{m}} m 1.3的前提是n远大于m。在n比较小的时候,它的估计误差就会很大。

Adaptive Counting

主要改进

Linear Counting和LogLog Counting的存储结构其实是兼容的,只要统计LogLog Counting的 ρ m a x \rho_{max} ρmax 是否为0就可以退化为Linear Counting。
既然两者的存储结构兼容,而又各自擅长n较小和n较大的情况,Adaptive Counting就提出通过寻找一个分段点,让两者的优点互补。
Linear Counting和LogLog Counting的标准误差为
S t d E r r o r l i n e a r c o u n i n t ( n ^ n ) = e t − t − 1 t m StdError_{linear_counint}(\frac{\hat{n}}{n}) = \frac{\sqrt{e^t-t-1}}{t\sqrt{m}} StdErrorlinearcounint(nn^)=tm ett1
S t d E r r o r l o g l o g c o u n t i n g ( n ^ n ) = 1.3 m StdError_{loglog counting}(\frac{\hat{n}}{n}) = \frac{1.3}{\sqrt{m}} StdErrorloglogcounting(nn^)=m 1.3

两式联立
e t − t − 1 t m = 1.3 m \frac{\sqrt{e^t-t-1}}{t\sqrt{m}} = \frac{1.3}{\sqrt{m}} tm ett1 =m 1.3

即可得到相交点 t ≈ 2.89 t \approx 2.89 t2.89,其中 t = n m t=\frac{n}{m} t=mn,此时Linear Counting的空桶率 β = e − t ≈ 0.051 \beta = e^{-t} \approx 0.051 β=et0.051
所以Adaptive Counting中,估算公式为:

n ^ = { α m m 2 Σ M m   if   0 ≤ β ≤ 0.051   − m ln ⁡ ( β )   if   0.051 ≤ β ≤ 1 \hat{n} = \begin{cases} \alpha_m{m2^{\frac{\Sigma{M}}{m}}} \, \text{if} \, 0 \le \beta \le 0.051 \\\ -m\ln(\beta) \, \text{if} \, 0.051 \le \beta \le 1 \end{cases} n^={αmm2mΣMif0β0.051 mln(β)if0.051β1

因为AC只是LC和LLC的简单组合,所以误差分析可以依照LC和LLC进行。值得注意的是,当β<0.051时,LLC最大的偏差不超过0.17%,因此可以近似认为是无偏的。

HyperLogLog Counting

主要改进

调和平均数以减少离群值影响

HLLC的第一个改进是使用调和平均数替代几何平均数。注意LLC是对各个桶取算数平均数,而算数平均数最终被应用到2的指数上,所以总体来看LLC取得是几何平均数。由于几何平均数对于离群值(例如0)特别敏感,因此当存在离群值时,LLC的偏差就会很大,这也从另一个角度解释了为什么n不太大时LLC的效果不太好。这是因为n较小时,可能存在较多空桶,而这些特殊的离群值强烈干扰了几何平均数的稳定性。

因此,HLLC使用调和平均数来代替几何平均数,可以有效抵抗离群值的扰动。使用调和平均数代替几何平均数后,估计公式变为如下:

n ^ = α m m 2 Σ 2 − M , α m = ( m ∫ 0 ∞ ( log ⁡ 2 ( 2 + u 1 + u ) ) m   d u ) − 1 \hat{n} =\frac{\alpha_m m^2}{\Sigma{2^{-M}}}, \quad \alpha_m = (m\int_0^{\infty}(\log_2(\frac{2+u}{1+u}))^m \, du)^{-1} n^=Σ2Mαmm2,αm=(m0(log2(1+u2+u))mdu)1

HLLC通过这样改进将误差从 1.3 m \frac{1.3}{\sqrt{m}} m 1.3 优化到了 1.04 m \frac{1.04}{\sqrt{m}} m 1.04,而空间复杂度与LLC相同。

分段偏差修正

给出了在n较小或较大时的偏差修正方案,具体来说
估 算 方 法 = { L i n e a r C o u n t i n g   i f   E ≤ 5 m 2   H y p e r L o g L o g C o u n t i n g   i f   5 m 2 < E ≤ 2 32 30   − 2 32 log ⁡ ( 1 − E 2 32 )   i f   E > 2 32 30 估算方法 = \begin{cases} \begin{aligned} Linear Counting\, &if \, E \le \frac{5m}{2} \\\ HyperLogLog Counting \, &if \, \frac{5m}{2} \lt E \le \frac{2^{32}}{30} \\\ -2^{32}\log(1-\frac{E}{2^{32}}) \, &if \, E \gt \frac{2^{32}}{30} \end{aligned}\end{cases} =LinearCounting HyperLogLogCounting 232log(1232E)ifE25mif25m<E30232ifE>30232

参考资料

《A Linear-Time Probabilistic Counting Algorithm for Database Applications》
《LogLog Counting of Large Cardinalities (Extended Abstract)》
《HyperLogLog: the analysis of a near-optimal cardinality estimation algorithm》
《Fast and Accurate Traffic Matrix Measurement Using Adaptive Cardinality Counting》
博客:http://blog.codinglabs.org/articles/algorithms-for-cardinality-estimation-part-i.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值