当前位置: 首页 > 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…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

【PX4飞控】mavros gps相关话题分析,经纬度海拔获取方法,卫星数锁定状态获取方法

使用 ROS1-Noetic 和 mavros v1.20.1&#xff0c; 携带经纬度海拔的话题主要有三个&#xff1a; /mavros/global_position/raw/fix/mavros/gpsstatus/gps1/raw/mavros/global_position/global 查看 mavros 源码&#xff0c;来分析他们的发布过程。发现前两个话题都对应了同一…...