Top-K

Top-K 是一种概率数据结构,允许您在数据流中找到最频繁的项目。

Top K 是 Redis Stack 中的一种概率数据结构,用于从流中估计 K 个最高排名的元素。

在这种情况下,“最高排名”意味着“具有最高数字或分数的元素”,其中分数可以是元素在流中出现的次数 - 从而使数据结构非常适合查找流中频率最高的元素。 一个非常常见的应用是检测网络异常和DDoS攻击,其中Top K可以回答以下问题:是否有突然增加的请求流量到同一地址或来自同一IP?

确实,与Count-Min Sketch的功能有一些重叠,但这两个数据结构有其不同之处,应适用于不同的使用场景。

Redis Stack 的 Top-K 实现基于 Junzhi Gong 等人提出的 HeavyKeepers 算法。它摒弃了一些旧的方法,如“计数所有”和“允许所有计数部分”,转而采用“指数衰减计数”策略,该策略对小流量(鼠标流)有偏见,而对大流量(大象流)的影响有限。此实现同时使用了两种数据结构:一个保存概率计数的哈希表(类似于 Count-Min Sketch),以及一个保存计数最高的 K 个项的最小堆。这确保了比之前的概率算法更高的准确性和更短的执行时间,同时将内存利用率保持在通常有序集合所需的一小部分。它还有一个额外的好处,即当元素被添加到或从 Top K 列表中移除时,能够获得实时通知。

用例

热门话题标签(社交媒体平台,新闻分发网络)

这个应用程序回答以下问题:

  • 在过去X小时内,人们提到最多的K个标签是什么?
  • 今天阅读/观看次数最高的K条新闻是什么?

数据流是来自社交媒体的传入帖子,从中你可以解析出不同的标签。

TOPK.LIST 命令的时间复杂度为 O(K*log(k)),因此如果 K 很小,就没有必要维护一个单独的集合或排序集合来存储所有的标签。你可以直接从 Top K 本身进行查询。

Example

这个例子将向你展示如何在网上购物时跟踪使用的关键词“bike”;例如,“bike store”和“bike handlebars”。请按照以下步骤进行。 ​

  • 使用TOPK.RESERVE来初始化一个具有特定参数的top K草图。注意:widthdepthdecay_constant参数可以省略,如果不存在,它们将分别设置为默认值7、8和0.9。 ​
> TOPK.RESERVE key k width depth decay_constant
  • 使用 TOPK.ADD 向草图添加项目。如你所见,可以同时添加多个项目。如果在添加额外项目时返回了一个项目,这意味着该项目被降级出前K项的最小堆,下面将意味着返回的项目不再在前5名中,否则返回 nil。这允许动态检测进入或退出前K列表的重击项目。 ​ 在下面的示例中,“pedals”取代了“handlebars”,在添加“pedals”后返回“handlebars”。还要注意,第二次添加“store”和“seat”时没有返回任何内容,因为它们已经在前K中。

  • 使用 TOPK.LIST 列出迄今为止输入的条目。 ​

  • Use TOPK.QUERY to see if an item is on the top K list. Just like TOPK.ADD multiple items can be queried at the same time.

尺寸

选择Top K草图的大小相对容易,因为您需要设置的唯一两个参数是您希望在列表中保留的元素数量(K)的直接函数。

如果你从已知你想要的k开始,你可以很容易地推导出宽度和深度:

width = k*log(k)
depth =  log(k)  # but a minimum of 5

对于decay_constant,你可以使用值0.9,这在许多情况下已被发现为最优,但你可以尝试不同的值,找到最适合你用例的值。

性能

在top-k中插入的时间复杂度为O(K + depth) ≈ O(K),查找的时间复杂度为O(K),其中K是列表中保留的顶部元素的数量,depth是使用的哈希函数的数量。

学术资源

参考文献

RATE THIS PAGE
Back to top ↑