caffine概率统计算法之Count-Min Sketch

Count-Min Sketch 算法详解

1. 什么是 Count-Min Sketch?

Count-Min Sketch(CMS)是一种概率型数据结构 ,用于在有限空间内高效地统计大量元素的频率(计数),尤其适合处理大规模数据流。

它的特点是:

  • 占用空间小(远小于为每个元素分配一个计数器)
  • 支持快速插入和查询
  • 统计结果有误差(但误差可控)

Count-Min Sketch 常用于网络流量统计、缓存频率统计(如 Caffeine 的 TinyLFU)、大数据分析等场景。

2. 算法原理

核心结构:二维计数数组 + 多个哈希函数

  • 设定 d d d 个哈希函数 h 1 , h 2 , . . . , h d h_1, h_2, ..., h_d h1,h2,...,hd,每个哈希函数对应一行数组,数组长度为 w w w。
  • 总体结构是 d × w d \times w d×w 的二维数组,每个元素初始为 0。
  • 每个哈希函数将输入元素映射到 0 , w − 1 0, w-1 0,w−1 的区间。

插入操作(add/put)

对于元素 x x x,每个哈希函数 h i h_i hi 计算 h i ( x ) h_i(x) hi(x),在第 i i i 行第 h i ( x ) h_i(x) hi(x) 列的计数器加一。
for i = 1 to d : count i h i ( x ) + = 1 \text{for } i = 1 \text{ to } d: \quad \text{count}ih_i(x) += 1 for i=1 to d:countihi(x)+=1

查询操作(estimate/count)

对于元素 x x x,查询每个哈希函数对应的计数器,返回最小值作为估计频率:
f ^ ( x ) = min ⁡ i = 1 d count i h i ( x ) \hat{f}(x) = \min_{i=1}^d \text{count}ih_i(x) f^(x)=i=1mindcountihi(x)

为什么取最小值?

由于哈希冲突,某些计数器可能被其它元素"污染"而偏大。取最小值能保证"不会高估太多"。

3. 误差分析与参数选择

  • 误差来源:哈希冲突导致频率被高估(不会低估)。
  • 误差上界:估计频率 f ^ ( x ) \hat{f}(x) f^(x) 至多比实际频率 f ( x ) f(x) f(x) 多 ε N \varepsilon N εN,其中 N N N 是总插入次数, ε \varepsilon ε 由数组宽度 w w w 控制。
  • 错误概率 δ \delta δ 由哈希函数个数 d d d 控制。

参数选择:

  • w = ⌈ e / ε ⌉ w = \lceil e / \varepsilon \rceil w=⌈e/ε⌉, d = ⌈ ln ⁡ ( 1 / δ ) ⌉ d = \lceil \ln(1/\delta) \rceil d=⌈ln(1/δ)⌉
  • 例如, ε = 0.01 \varepsilon = 0.01 ε=0.01, δ = 0.001 \delta = 0.001 δ=0.001,则 w = 271 w=271 w=271, d = 7 d=7 d=7

4. 伪代码示例

java 复制代码
class CountMinSketch {
    int[][] table; // d x w
    HashFunction[] hashFunctions; // d个哈希函数

    public CountMinSketch(int d, int w) {
        table = new int[d][w];
        hashFunctions = new HashFunction[d];
        // 初始化哈希函数
    }

    public void add(String key) {
        for (int i = 0; i < d; i++) {
            int idx = hashFunctions[i].hash(key) % w;
            table[i][idx]++;
        }
    }

    public int estimate(String key) {
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < d; i++) {
            int idx = hashFunctions[i].hash(key) % w;
            min = Math.min(min, table[i][idx]);
        }
        return min;
    }
}

5. 优缺点

优点:

  • 空间效率高,适合大数据场景
  • 查询和插入都是 O ( d ) O(d) O(d),非常快
  • 误差可控

缺点:

  • 频率估计有误差(高估,不会低估)
  • 不支持删除(标准 CMS 只有加法)

6. 应用场景

  • 缓存频率统计(如 Caffeine 的 TinyLFU)
  • 网络包计数、热门关键词统计
  • 数据流分析、反垃圾邮件等

好的,下面用图示和简化说明帮助你理解 Count-Min Sketch 算法。

示例解释

1. 数据结构图示

假设我们有 3 个哈希函数,每个哈希函数对应一行,数组长度为 8:

ini 复制代码
哈希函数1: [0] [1] [2] [3] [4] [5] [6] [7]
哈希函数2: [0] [1] [2] [3] [4] [5] [6] [7]
哈希函数3: [0] [1] [2] [3] [4] [5] [6] [7]

初始时,每个格子都是 0。


2. 插入元素

假设我们插入元素 "A":

  • 哈希函数1("A") = 3
  • 哈希函数2("A") = 6
  • 哈希函数3("A") = 1

我们就在对应位置加 1:

ini 复制代码
哈希函数1: [0] [0] [0] [1] [0] [0] [0] [0]
哈希函数2: [0] [0] [0] [0] [0] [0] [1] [0]
哈希函数3: [0] [1] [0] [0] [0] [0] [0] [0]

再插入 "B":

  • 哈希函数1("B") = 5
  • 哈希函数2("B") = 3
  • 哈希函数3("B") = 1
ini 复制代码
哈希函数1: [0] [0] [0] [1] [0] [1] [0] [0]
哈希函数2: [0] [0] [0] [1] [0] [0] [1] [0]
哈希函数3: [0] [2] [0] [0] [0] [0] [0] [0]

注意,"B" 和 "A" 在哈希函数3的位置冲突了,所以第 1 列变成了 2。


3. 查询元素频率

查询 "A" 的频率:

  • 哈希函数1("A") = 3,值为 1
  • 哈希函数2("A") = 6,值为 1
  • 哈希函数3("A") = 1,值为 2(因为冲突)

取最小值:1

所以,"A" 的估计频率是 1。


查询 "B" 的频率:

  • 哈希函数1("B") = 5,值为 1
  • 哈希函数2("B") = 3,值为 1
  • 哈希函数3("B") = 1,值为 2

取最小值:1

所以,"B" 的估计频率也是 1。


4. 图解流程

rust 复制代码
插入 "A":
哈希函数1 --> 3号格 +1
哈希函数2 --> 6号格 +1
哈希函数3 --> 1号格 +1

插入 "B":
哈希函数1 --> 5号格 +1
哈希函数2 --> 3号格 +1
哈希函数3 --> 1号格 +1(与"A"冲突)

查询 "A":
查3号格、6号格、1号格,取最小值

查询 "B":
查5号格、3号格、1号格,取最小值

5. 总结

  • Count-Min Sketch 用多个哈希函数,把每个数据插入多个计数器。
  • 查询时取所有计数器的最小值,避免哈希冲突导致频率被高估太多。
  • 空间很省,适合大数据流场景。

如果需要更复杂的图示(比如流程图或动画),可以用白板或画图工具,但上面已经用文字和表格清楚表达了核心流程。

相关推荐
倒头就睡的小比特2 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!2 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼3 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光3 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark3 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her13 天前
并查集-听课笔记
笔记·算法·并查集
码流子3 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven3 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark3 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218613 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法