当前位置: 首页 > news >正文

HyperLogLog 的原理 详解

        HyperLogLog(简称 HLL)是一种用于近似计数(特别是基数估计,Cardinality Estimation)的算法,它能够在大数据场景中高效地估计集合中不同元素的数量,尤其适用于数据流的情况。HyperLogLog 相较于传统的计数方法,具备非常低的空间复杂度,同时又能提供准确的估计结果。它是 LogLog 算法的改进版。

一、背景与需求

在很多数据处理场景中,我们需要估算数据流或大规模集合中不同元素的数量。例如:

  • 网站访问者的去重统计。
  • 网络中独立IP的计数。
  • 社交网络中的独立用户数量。

        对于这些问题,直接计算集合的基数(即集合中独立元素的数量)是非常消耗内存和计算资源的,尤其在数据量巨大的情况下。因此,我们需要一种空间复杂度低且计算高效的算法来近似这个基数。

二、基本概念

        HyperLogLog 的设计目标是使用较小的内存空间(通常是常数空间)来对大数据集中的不同元素的基数进行估计。

  • 估计的精度:HyperLogLog 的估计值是一个近似值,但通常精度非常高。
  • 空间复杂度:HyperLogLog 使用 O(log⁡(log⁡(n))) 的空间来存储结果,其中 n 是数据集中的元素数量。这个空间复杂度比传统的哈希集合(需要 O(n) 空间)要小得多。

三、工作原理

HyperLogLog 基于以下几个关键的思想:

  1. 哈希函数:HyperLogLog 使用哈希函数将数据项映射到一个范围内。哈希函数的设计要求其具有均匀性,即对于不同的输入,它能生成均匀分布的输出。

  2. 桶(Buckets):HyperLogLog 使用多个桶来存储中间结果。每个桶保存一个整数值,表示该桶所记录的哈希值的前导零的数量。

  3. 最大前导零计数:对于每个元素,通过哈希函数计算其哈希值,然后记录该哈希值二进制表示中的前导零的数量。假设哈希值的长度为 L 位,那么每个桶存储的是哈希值中的前导零数。

  4. 桶的更新规则:每次插入一个新元素时,计算该元素的哈希值,并找到该哈希值二进制表示中的前导零的个数。然后更新对应桶的值,即该桶记录的值为该桶当前值和前导零数的最大值。

  5. 基数估计:最终的基数估计值是通过对所有桶中记录的前导零数的值进行合成计算得到的。

1.1 哈希映射与前导零

        首先,假设我们对一个元素应用一个哈希函数 H,得到的哈希值是一个 m 位的二进制字符串。我们关心的是该哈希值中从左至右的前导零的数量。例如,如果哈希值为 0001011001,则前导零的数量为 3

1.2 桶(Registers)

        HyperLogLog 使用多个桶,每个桶记录一个整数值,表示该桶对应哈希值的最大前导零数。假设我们有 b 个桶,那么我们将输入的哈希值映射到其中的一个桶。

        通过哈希函数,我们将输入数据映射到一个桶。然后,对于每个数据点,计算其哈希值中前导零的数量,并更新该桶的值。具体而言,如果哈希值的前导零数大于该桶当前记录的前导零数,则更新该桶的值。

1.3 基数估算

        HyperLogLog 使用一种名为 Harmonic Mean 的方法来估算基数。为了避免估算偏差,最终的基数估算结果是通过所有桶的统计信息计算的。

  • 计算所有桶中值的平均数。
  • 使用此平均数来推算出总的基数。

具体计算公式如下:

                                E=\alpha _{m}*m^{2}*2^{-Z}

其中:

  • E 是基数估算值。
  • m 是桶的数量(桶的数量等于 HyperLogLog 中注册器的数量)。
  • Z 是桶中记录的前导零数的平均值。
  • \alpha _{m} 是一个常数,具体值与桶的数量 m 有关。

四、空间复杂度与精度

        HyperLogLog 的空间复杂度主要由桶的数量 m 决定。每个桶通常存储一个整数值,这个整数值代表前导零的最大值,因此每个桶所需的存储空间是常数级别的。通常,为了保持足够的精度,我们会选择 m 为 2^{n} 的形式,其中 n 为桶数的对数。

精度:HyperLogLog 的误差率(标准差)与桶的数量 m 相关。桶数越多,精度越高,但需要更多的内存空间。一般来说,HyperLogLog 的误差范围是 ±2%。

五、源代码实现(Python 示例)

下面是一个简化的 HyperLogLog 的 Python 实现:

import hashlib
import mathclass HyperLogLog:def __init__(self, b):self.b = b  # number of registers (buckets)self.m = 1 << b  # number of registers (m = 2^b)self.data = [0] * self.m  # initialize registers to 0def _hash(self, value):# Use hashlib to compute a hash of the input valuereturn int(hashlib.md5(str(value).encode('utf8')).hexdigest(), 16)def _rho(self, x):# Count the number of leading zeros in the binary representation of xreturn (x ^ (1 << x.bit_length() - 1)).bit_length() + 1def add(self, value):# Hash the value and compute the register indexhash_value = self._hash(value)register_index = hash_value & (self.m - 1)  # Use the lower b bits for the index# Update the corresponding register with the max rho valueself.data[register_index] = max(self.data[register_index], self._rho(hash_value))def estimate(self):# Use the registers to estimate the cardinalityZ = 1.0 / sum([2.0 ** -reg for reg in self.data])E = (self.m ** 2) * Z# Apply bias correction for small cardinalitiesif E <= 2.5 * self.m:V = self.data.count(0)if V > 0:E = self.m * math.log(self.m / V)# Large cardinalities correctionif E > (1 / 30.0) * (1 << 32):E = -(1 << 32) * math.log(1 - E / (1 << 32))return E# Example usage:
hll = HyperLogLog(15)  # Initialize with 2^15 registers
for i in range(10000):hll.add(i)
print("Estimated cardinality:", hll.estimate())

代码解释:
  1. 初始化:HyperLogLog 类接受一个参数 b,指定桶的数量为 m=2^{b}。每个桶存储一个整数值,表示前导零的数量。
  2. 哈希函数:_hash 方法使用 MD5 哈希来处理输入值,并返回一个整数。
  3. 更新桶:add 方法接受一个元素,计算其哈希值,并更新相应桶的值。
  4. 估算基数:estimate 方法使用所有桶的值来估算数据集的基数,并考虑了小基数和大基数的修正。

六、总结

        HyperLogLog 是一个基于哈希的概率算法,具有非常高的内存效率,尤其适用于需要快速估算基数的大数据场景。它通过哈希映射和前导零统计来估计基数,在保证低空间复杂度的同时,仍然提供较为准确的结果。尽管它是一个近似算法,但在很多实际应用中,估算误差足够小,能够满足需求。

相关文章:

HyperLogLog 的原理 详解

HyperLogLog&#xff08;简称 HLL&#xff09;是一种用于近似计数&#xff08;特别是基数估计&#xff0c;Cardinality Estimation&#xff09;的算法&#xff0c;它能够在大数据场景中高效地估计集合中不同元素的数量&#xff0c;尤其适用于数据流的情况。HyperLogLog 相较于传…...

OCR、语音识别与信息抽取:免费开源的AI平台在医疗领域的创新应用

一、系统概述 在医疗行业中&#xff0c;大量数据来自手写病历、医学影像报告、患者对话记录等非结构化数据源。这些数据常常存在信息碎片化和管理困难的问题&#xff0c;给医务人员的工作带来了不便。思通数科AI多模态能力平台正是为了解决这一行业痛点而生&#xff0c;产品集…...

苍穹外卖Bug集合

初始化后端项目运行出现以下问题 以上报错是因为maven和jdk版本不符合&#xff0c;需要将jdk改成17&#xff0c;mavne改成3.9.9...

小菜家教平台(一):基于SpringBoot+Vue打造一站式学习管理系统

前言 现在已经学习了很多与Java相关的知识&#xff0c;但是迟迟没有进行一个完整的实践&#xff08;之前这个项目开发到一半&#xff0c;很多东西没学搁置了&#xff0c;同时原先的项目中也有很多的问题&#xff09;&#xff0c;所以现在准备从零开始做一个基于SpringBootVue的…...

PyCharm中pylint安装与使用

目录 1. 安装插件2. pycharm中使用该功能3. 命令行使用 1. 安装插件 然后重启 2. pycharm中使用该功能 3. 命令行使用 前提是先 pip install pylint pylint demo01.py下面红框内容的意思是&#xff0c;得到10分/ 满分10分&#xff0c;上次运行获得8.33分&#xff0c;经调整…...

一篇文章了解TCP/IP模型

TCP/IP模型&#xff0c;即传输控制协议/互联网协议模型&#xff08;Transmission Control Protocol/Internet Protocol Model&#xff09;&#xff0c;是互联网及许多其他网络上使用的分层通信模型。以下是对TCP/IP模型的详细介绍&#xff1a; 一、定义与组成TCP/IP模型是一个四…...

python文字识别---基于百度api

百度智能云账户注册&#xff1a;https://console.bce.baidu.com/ai/#/ai/ocr/app/list 获取appid、api_key、secret_key from aip import AipOcr import osconfig {appid: 116122887,api_key: DAQnt...,secret_key: 5S0Kpyh.... }# 初始化 AipOcr 客户端 client AipOcr(c…...

linux下linuxdeployqt打包过程

一 、linuxdeployqt下载安装 1.下载linuxdeployqt依赖拷贝工具 下载地址&#xff1a;https://github.com/probonopd/linuxdeployqt/releases 2.为了方便使用&#xff0c;将名字改短一点&#xff1a;mv linuxdeployqt-6-x86_64.AppImage linuxdeployqt3.修改下载的文件的可执行…...

【拥抱AI】AI大模型在软件开发中的应用如何保证数据安全?

随着AI大模型在软件开发中的广泛应用&#xff0c;数据安全问题变得尤为重要。确保数据的安全不仅关乎企业的声誉和合规性&#xff0c;还直接影响到用户对产品的信任。以下是几种常见的方法和最佳实践&#xff0c;以确保在使用AI大模型时的数据安全。 1. 数据加密 传输加密&a…...

python爬取旅游攻略(1)

参考网址&#xff1a; https://blog.csdn.net/m0_61981943/article/details/131262987 导入相关库&#xff0c;用get请求方式请求网页方式&#xff1a; import requests import parsel import csv import time import random url fhttps://travel.qunar.com/travelbook/list.…...

C++网络编程之IO多路复用(一)

概述 在C网络编程中&#xff0c;处理并发连接是一个非常关键的核心问题。为了有效管理来自多个客户端的请求&#xff0c;服务器需要能够同时监听多个套接字上的事件&#xff0c;这通常通过IO多路复用来实现。 IO多路复用是一种工作机制&#xff0c;它可以让程序监视多个文件描述…...

vscode在windows和linux如何使用cmake构建项目并make生成可执行文件,两者有什么区别

vscode在windows和linux如何使用cmake构建项目并make生成可执行文件&#xff0c;两者有什么区别 windows默认使用的是最新的visual studio&#xff0c;而linux默认就是cmake 文章目录 vscode在windows和linux如何使用cmake构建项目并make生成可执行文件&#xff0c;两者有什么…...

Antd Vue中使用table组件把相同名称的合并单元格---只需两步

当前效果&#xff1a; 想要的效果&#xff1a; 第一步&#xff1a;在获取table数据的地方处理数据 function getTableList () {getDataList().then(res > {if (res.code 200 && res.data) {const list res.datalet columnIndex 0 //第一条数据let rowSpan …...

cmake中execute_process详解

execute_process 是 CMake 中一个非常强大的命令&#xff0c;用于在构建过程中执行外部程序或脚本。它提供了丰富的选项来控制执行过程&#xff0c;并可以捕获输出、错误和返回码。以下是 execute_process 的详细解析&#xff1a; 基本语法 execute_process(COMMAND <comm…...

搜维尔科技:使用Sensglove Nova2触觉反馈手套遥操作机器人操作

使用Sensglove Nova2触觉反馈手套遥操作机器人操作 搜维尔科技&#xff1a;使用Sensglove Nova2触觉反馈手套遥操作机器人操作...

企业HR如何选对一款智能招聘软件?

随着招聘市场的竞争加剧和求职者期望的提升&#xff0c;传统的招聘方式已经难以满足企业的需求。智能招聘软件应运而生&#xff0c;成为企业HR提升招聘效率、优化招聘流程、增强雇主品牌吸引力的关键工具。然而&#xff0c;市场上的智能招聘软件琳琅满目&#xff0c;如何选择一…...

任务中心全新升级,新增分享接口文档功能,MeterSphere开源持续测试工具v3.4版本发布

2024年11月5日&#xff0c;MeterSphere开源持续测试工具正式发布v3.4版本。 在这一版本中&#xff0c;系统设置方面&#xff0c;任务中心支持实时查看系统即时任务与系统后台任务&#xff1b;接口测试方面&#xff0c;新增接口文档分享功能、接口场景导入导出功能&#xff0c;…...

书生大模型第三关Git 基础知识

关卡编号&#xff1a;L0G3000 任务一 破冰行动 fork仓库&#xff0c;注意这里不要勾选Copy branch Only!!!&#xff0c;因为后面课程中会使用到class分支&#xff1a; 克隆仓库&#xff1a; 移动分支&#xff1a; 创建自己的分支&#xff1a; 创建id.md文档&#xff0c;…...

WordPress 中最佳的维护服务:入门级用户指南

如果你是WordPress网站管理员&#xff0c;一定知道网站维护既耗时又复杂。然而&#xff0c;保持网站的正常运行和安全却至关重要。为了让你轻松应对这个挑战&#xff0c;我们总结了一些适合新手和小型网站的维护服务。本文将介绍两款适合初学者的维护服务&#xff1a;FixMySite…...

前端使用Luckysheet把返回的base64或二进制文件流格式,实现xlsx文件预览

xlsx文件预览 Luckysheet是什么&#xff1f;代码实现xlsx文件预览引入luckysheet的相关依赖安装luckyexcel指定一个表格容器实现逻辑 Luckysheet是什么&#xff1f; Luckysheet &#xff0c;一款纯前端类似excel的在线表格&#xff0c;功能强大、配置简单、完全开源。 Luckys…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下&#xff1a; avformat_open_input 精简后的代码如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...

在Zenodo下载文件 用到googlecolab googledrive

方法&#xff1a;Figshare/Zenodo上的数据/文件下载不下来&#xff1f;尝试利用Google Colab &#xff1a;https://zhuanlan.zhihu.com/p/1898503078782674027 参考&#xff1a; 通过Colab&谷歌云下载Figshare数据&#xff0c;超级实用&#xff01;&#xff01;&#xff0…...

RFID推动新能源汽车零部件生产系统管理应用案例

RFID推动新能源汽车零部件生产系统管理应用案例 一、项目背景 新能源汽车零部件场景 在新能源汽车零部件生产领域&#xff0c;电子冷却水泵等关键部件的装配溯源需求日益增长。传统 RFID 溯源方案采用 “网关 RFID 读写头” 模式&#xff0c;存在单点位单独头溯源、网关布线…...