如何确定事件发生率(移动平均值)是否超过阈值

时间:2019-05-29 10:24:19

标签: algorithm mainframe moving-average smoothing rexx

编辑添加的信息

最初,这只是关于一般算法和与语言/平台无关的内容。但是,我将自己回答这个问题,答案实际上是针对所使用的工具的。

这用于使用运行REXX脚本的Ops / MVS自动化工具在z / OS下的IBM大型机上进行事件检测。

因此发布的答案可能适用于Python,Perl,bash,Java等;只是在这种特殊情况下使用的产品具有特定的功能即可解决问题。

添加的信息结尾

我的问题与此非常相似:

How to calculate continuous smooth event rate based on event times?

这将是一个答案:

  

这可以通过移动平均线来实现。参加您最近的N个活动   其中N是平均窗口的大小。计算时间   这N个事件的第一个和最后一个之间的差异。如果你   以秒为单位进行测量,并希望每分钟的事件发生率   然后将60秒除以您表示的时间差   秒,然后乘以N-1。

除了我想避免存储有关先前事件的信息。我也只对移动平均线超过阈值感兴趣,所以我对保持汇率趋势不感兴趣。

例如,我想知道我是否每分钟获得3个以上的事件。这是我的第一种方法:

  1. 当第一个事件发生时,我创建一个计数1并记录 开始时间。
  2. 当另一个事件发生时,我增加计数并计算 计数和经过时间的比率
  3. 如果费率超出允许值,则生成警报。

我意识到这是行不通的,因为如果您在一周前进行了一次活动,然后在最后一分钟才进行了10次活动,那么平均“费率”为一周11次,即3.6天/天,而不是当前的费率10 / min。

所以我正在考虑尝试以下方法:

  1. 当第一个事件发生时,我创建一个计数1并记录 开始时间。
  2. 当另一个事件发生时,如果自上一个事件以来的时间超出了我要测量速率的时间间隔(在我的示例中为1分钟),我将有效地丢弃前一个事件并记录计数1和当前时间作为新的开始时间(因为距上一个事件以来已经超过1分钟,所以速率不能超过x / min吗?)。
  3. 如果自上一个事件以来的时间未超过监视时间 间隔,增加计数并从计数中计算速率 和经过的时间
  4. 如果费率超出允许值,则生成警报。

这似乎很简单,但是关于SO的其他帖子(具体来说是这个问题:Estimating rate of occurrence of an event with exponential smoothing and irregular events,它的答案是:https://stackoverflow.com/a/23617678/1430420)似乎暗示着它比我想的要多得多。

2 个答案:

答案 0 :(得分:1)

Ops / MVS通过“ OPSTHRSH”功能内置了此功能:

https://docops.ca.com/ca-opsmvs/13-5/en/reference-information/command-and-function-reference/ops-rexx-built-in-functions/opsthrsh-function

对于这种特殊情况,我们可以按以下方式调用它:

if OPSTHRSH('A',60) > 3 then do something...

OPSTHRESH('A',60)将返回一个计数,该计数是在60秒的时间内对当前地址空间(任务)触发了当前事件的次数。如果该值超过了我的触发水平,请采取措施。收到第一个事件后60秒,事件计数将重置。

答案 1 :(得分:0)

使用以下伪代码:

boolean update(long timestamp, History h, int windowSize, int minEventsToTrigger) {
    h.removeOlderThan(timestamp - windowSize);
    h.addEvent(timestamp);
    return h.size() >= minEventsToTrigger;
}

hcircular buffer的地方,它通过以下操作存储时间戳:

  • removeOlderThan(t):删除所有在t之前发生的事件。此操作将摊销O(1),因为每个事件将被精确删除一次,并且事件(最早的事件除外)将永远不会被查询超过一次。

  • addEvent(t):在缓冲区的末尾添加一个事件,或者如果缓冲区已满,则首先删除最早的事件,然后添加新的事件。 O(1)操作;而将旧事件替换为新事件,则可以确保事件的突然涌入不会淹没系统,不需要额外的内存或破坏此代码-只要minEventsToTrigger小于h的容量,结果将始终是正确的。

我相信,此伪代码在时间上可能是最佳的,并且在空间上也可能是最佳的。重要的是,它不需要任何动态分配。

如果在给定新事件的情况下,在update个时间单位内至少已收到minEventsToTrigger,则windowSize函数返回true,否则返回false。请注意,仅打算在收到每个事件时调用它,因此只能准确地rising edges(直到下一个事件才检测到下降沿)。如果您想对此进行补救,则有两种选择:

  • 定期轮询以查看在调用h.removeOlderThan(timestamp - windowSize);之后,条件return h.size() >= minEventsToTrigger;是否不再为真。如果事件很少发生,这可能是浪费的。如果仅在触发警报时执行此操作,则可以节省很多不必要的操作。
  • 使用某种计时器机制,一旦触发警报,就在最早的事件到期后立即唤醒。这样可以保证事件到期与h.size() >= minEventsToTrigger检查之间的最小延迟。