基数计数——HyperLogLog

所谓的基数计数就是统计一组元素中不重复的元素的个数。如统计某个网站的UV,或者用户搜索网站的关键词数量;再如对一个网站分别统计了三天的UV,现在需要知道这三天的UV总量是多少,怎么融合多个统计值。

1、方法

(假设元素个数为m,去重后个数为n)

1、集合操作去重

时间复杂为O(m2),空间复杂度随元素个数线性增长。数据量一大就崩了。

2、B+树

将数据插入到B+树中达到去重目的,然后顺序访问叶节点链从而得到n值。时间复杂的为O( lgm + n ),内存亦随元素个数线性增长。数据量一大就崩了。

3、BitMap

用位数组来表示各元素是否出现,每个元素对应一位,所需的总内存为n bit。能大大减少内存占用且位操作迅速。

如果要统计1亿个数据的基数值,大约需要内存100000000/8/1024/1024 ≈ 12M,内存减少占用的效果显著。然而统计一个对象的基数值需要12M,如果统计10000个对象,就需要将近120G,同样不能广泛用于大数据场景。

4、概率算法

实际上目前还没有发现更好的在大数据场景中准确计算基数的高效算法,因此在不追求绝对准确的情况下,使用概率算法算是一个不错的解决方案。概率算法不直接存储数据集合本身,通过一定的概率统计方法预估基数值,这种方法可以大大节省内存,同时保证误差控制在一定范围内。

目前用于基数计数的概率算法包括:

  • Linear Counting(LC):早期的基数估计算法,LC在空间复杂度方面并不算优秀,实际上LC的空间复杂度与上文中简单bitmap方法是一样的(但是有个常数项级别的降低),都是O(Nmax);
  • LogLog Counting(LLC):LogLog Counting相比于LC更加节省内存,空间复杂度只有O(log2(log2(N?max)));
  • HyperLogLog Counting(HLL):HyperLogLog Counting是基于LLC的优化和改进,在同样空间复杂度情况下,能够比LLC的基数估计误差更小。

2、HyperLogLog

参考资料

1、神奇的HyperLogLog算法 - CSDN

2、原始论文:Loglog Counting of Large Cardinalities

原文地址:https://www.cnblogs.com/z-sm/p/9337648.html

时间: 2024-10-19 09:22:34

基数计数——HyperLogLog的相关文章

【原创】算法分享(4)Cardinality Estimate 基数计数概率算法

读过<编程珠玑>(<Programming Pearls>)的人应该还对开篇的Case记忆犹新,大概的场景是: 作者的一位在电话公司工作的朋友想要统计一段时间内不同的电话号码的个数,电话号码的数量很大,当时的内存很小,所以不能把所有的电话号码全部放到内存来去重统计,他的朋友很苦恼. 作者聪明的想到了用bit数组来解决问题,每个电话号码可以映射为bit数组的index,bit数组初始状态所有位为0,所有电话号码逐一处理:将bit数组对应位置为1,处理完之后统计bit数组中有多少个1即

Redis常用命令(三)有序集合键、HyperLogLog键

zet 有序集合,元素为string类型,元素具有唯一性,不重复.每个元素都会关联一个double类型的score,表示权重,通过权重将元素从小到大排序.没有修改操作,虽然每个元素必不相同,但是score可以相同 zadd key score1 member1 score2 member2 ...  # 添加 zadd fruits 1.0 apple 2.4 banana 4 watermelon 5 orange # 返回指定范围内的元素,索引从左侧开始,第一个元素为0, # 索引可以是负数

解读Cardinality Estimation&lt;基数估计&gt;算法(第一部分:基本概念)

基数计数(cardinality counting)是实际应用中一种常见的计算场景,在数据分析.网络监控及数据库优化等领域都有相关需求.精确的基数计数算法由于种种原因,在面对大数据场景时往往力不从心,因此如何在误差可控的情况下对基数进行估计就显得十分重要.目前常见的基数估计算法有Linear Counting.LogLog Counting.HyperLogLog Counting及Adaptive Counting等.这几种算法都是基于概率统计理论所设计的概率算法,它们克服了精确基数计数算法的

reids HyperLoglog

关于 Redis HyperLogLog 在说明 HyperLogLog 之前,我们需要先了解一个概念:基数统计.维基百科中的解释是: cardinality of a set is a measure of the “number of elements“ of the set 它的意思是:一个集合(注意:这里集合的含义是 Object 的聚合,可以包含重复元素)中不重复元素的个数.例如集合 {1,2,3,1,2},它有5个元素,但它的基数/Distinct 数为3. 基数的应用实例 下面通过

干货驾到:Redis5.0支持的新功能说明

Redis5.0支持的新特性说明 文章来自华为云帮助中心华为云DCS的Redis5.x版本继承了4.x版本的所有功能增强以及新的命令,同时还兼容开源Redis5.x版本的新增特性. Stream数据结构 Stream是Redis 5.0引入的一种新数据类型,它是一个全新的支持多播的可持久化消息队列. 点击下方链接,可以了解更多详情. https://www.huaweicloud.com/product/dcs.html Redis Stream的结构示意图如图7-1所示,它是一个可持久化的数据

Bloom filter(布隆过滤器)概念与原理

写在前面 在大数据与云计算发展的时代,我们经常会碰到这样的问题.我们是否能高效的判断一个用户是否访问过某网站的主页(每天访问量上亿)或者需要统计网站的pv.uv.最直接的想法是将所有的访问者存起来,然后每次用户访问的时候与之前集合进行比较.不管是将访问信息存在内存(或数据库)都会对服务器造成非常大的压力.那是否存在一种方式,容忍一定的错误率,高效(计算复杂度.空间复杂度)的实现访问量信息的跟踪.统计呢?接下来介绍的布隆过滤器(BloomFilter)就可以满足当前的使用场景(注释:基数计数法同样

黑马程序员_IOS开发_Objective-C学习笔记_基本数据类型

 1.数据类型和常量: 我们在做IOS程序开发的时候使用的最多的恐怕就是基本数据类型,在Objective-c中提供了4种基本的数据类型:int float double以及char. 1.1声明为int的变量只能用于保存整形值. 1.2声明为float类型的变量可存储浮点类型值(即包含小数位数).. 1.3double类型和float类型一样,只不过前者的精度大约是后者的2倍. 1.4最后是char 数据类型,char类型可用来存储单个字符,例如字母a,数字6,或是一个分号.或者通过char指

Percona TokuDB

Percona TokuDB Percona TokuDB. 1 1.     TokuDB说明... 1 2.     TokuDB安装... 1 3.     使用TokuDB. 1 3.1 快速插入和富索引... 1 3.2 聚集secondary索引... 1 3.3 在线索引创建... 1 3.4 在线添加,删除,扩展,重命名列... 1 3.5            压缩细节... 1 3.6 修改表的压缩... 1 3.7 无io读复制... 1 3.8 事务和ACID兼容恢复..

在Visual C++中使用内联汇编

一.内联汇编的优缺点 因为在Visual C++中使用内联汇编不需要额外的编译器和联接器,且可以处理Visual C++中不能处理的一些事情,而且可以使用在C/C++中的变量,所以非常方便.内联汇编主要用于如下场合: 1.使用汇编语言写函数: 2.对速度要求非常高的代码: 3.设备驱动程序中直接访问硬件: 4."Naked" Call的初始化和结束代码. //(."Naked",理解了意思,但是不知道怎么翻译^_^,大概就是不需要C/C++的编译器(自作聪明)生成的