hyperloglog基数统计原理分析
从LogLog说起,其算法完整的基数计算公式如下:
那么hyperloglog与loglog不同的是采取调和平均数,计算公式:
问题1:hyperloglog怎么去重,而避免重复计数?
hyperloglog将需要被存储的内容计算得到随机分布的hash编码(随机分布128位的hash编码可模拟伯努利过程),那么相同的内容计算的哈希编码相同,这么就实现了去重。
问题2:伯努利过程是通过大量的实验策略,hyperloglog小数据量存储精确度误如何保证低?
Hyperloglog调和平均数,调和平均数保证了,平均值会总体向小值偏近。
举个例子:有4个桶,每个桶有2个bit位。那么有字符串计算hash值后有4位:10001,取低二位被分配到第1个桶,取高3位第一次出现1的位置为第3位。
那么,当content=1,此时根据loglog,平均数计算: 2^((3+0+0+0)/4)=1.7,DVLL=141.7=7个计数。
根据hyperloglog,调和平均数计算:
4/(1/20+1/20+1/20+1/23)=4/3.2=1.3,DVHLL=4*1.3=5个计数。
即使这样,那么显然精度也不好。其实,数据量是有一个阈值规则,使用LinerCount计数:
if DV < (5 / 2) * m:
DV = m * log(m/V)
v代表的是空桶数量,m为桶数。小数据量必然造成大量空桶。
此时,(5/2)4=10,显然,计数值 < 10,这时会改为根据LinerCount算法计数,那么修正后:
DDHLL=4ln(4/3)=4*0.12=1.1,四舍五入计数为1。
问题3:hyperloglog海量数据计算?
在伯努利过程实验中,其概率分布为0-1分布。伯努利过程的0-1分布事件发生与不发生的概率都为1/2。使用随机分布特征表现良好的MurmurHash算法计算得出二进制编码模拟伯努利过程。次数足够多实验后(超出数据量阈值),最大似然估计可以的得出伯努利过程次数n=2^k_max (k_max最大一次的重试数值)
优质文章参考:
http://www.rainybowe.com/blog/2017/07/13/%E7%A5%9E%E5%A5%87%E7%9A%84HyperLogLog%E7%AE%97%E6%B3%95/index.html
https://www.jianshu.com/p/55defda6dcd2