在线估计四分位数而不存储观测值


13

我需要在不存储观测值的情况下,根据大量数据实时计算四分位数(Q1,中位数和Q3)。我首先尝试了P平方算法(Jain / Chlamtac),但对它却不满意(CPU使用量过多,至少对于我的数据集的精度没有把握)。

我现在使用FAME算法(Feldman / Shavitt)动态估算中值,然后尝试推导该算法以计算Q1和Q3:

M = Q1 = Q3 = first data value 
step =step_Q1 = step_Q3 = a small value
for each new data :
        # update median M 
        if M > data:
            M = M - step
        elif M < data:
            M = M + step
        if abs(data-M) < step:
            step = step /2

        # estimate Q1 using M
        if data < M:
            if Q1 > data:
                Q1 = Q1 - step_Q1
            elif Q1 < data:
                Q1 = Q1 + step_Q1
            if abs(data - Q1) < step_Q1:
                step_Q1 = step_Q1/2
        # estimate Q3 using M
        elif data > M:
            if Q3 > data:
                Q3 = Q3 - step_Q3
            elif Q3 < data:
                Q3 = Q3 + step_Q3
            if abs(data-Q3) < step_Q3:
                step_Q3 = step_Q3 /2

要恢复,它仅使用动态获取的中值M将数据集一分为二,然后对Q1和Q3重新使用相同的算法。

这似乎以某种方式起作用,但是我无法证明(我不是数学家)。有缺陷吗?我将不胜感激任何建议或最终其他适合该问题的技术。

非常感谢您的帮助 !

====编辑=====

对于那些对此类问题感兴趣的人,几周后,我最终以简单的方式使用了带有100个值的revervoir的Reservoir Sampling,这给了我非常令人满意的结果。


您是否在寻找证据证明Q1和Q2会收敛到真实的分位数,因为示例数量的增加方式类似于链接的幻灯片中的马尔可夫链分析?在实现方面,上述算法似乎没有缺陷(我在R中测试了标准法线的近似分位数,并且该算法工作正常)。
Theja 2014年

1
@Theja谢谢,我不是在寻找证据(太多的工作),而只是提供建议和评论。我所看到的主要问题是,如胡布尔指出的那样,将计算基于中位数的运行估计。
Louis Hugues 2014年

Answers:


3

中位数是观察值的1/2下降到下方和1/2上升到的点。同样,第25个百分位数是最小值和中位数之间的数据的中位数,第75个百分位数是中位数和最大值之间的数据的中位数,所以,是的,我想您会稳固地应用您首先使用的任何中位数算法整个数据集对其进行分区,然后对两个结果进行分区。

更新

有关stackoverflow的问题引出了这篇论文:Raj Jain,Imrich Chlamtac:用于动态计算数量和直方图的P²算法,无需存储观测值。公社 ACM 28(10):1076-1085(1985),摘要表明您可能对此很感兴趣:

提出了一种启发式算法,用于中位数和其他分位数的动态计算。估计值是在生成观察值时动态生成的。观测值不存储;因此,无论观察次数多少,该算法的存储需求都非常小且固定。这使其非常适合在可用于工业控制器和记录器的分位数芯片中实现。该算法进一步扩展到直方图绘图。分析了算法的准确性。


4
此答复忽略了两个微妙的观点,一个不重要,但另一个可能非常重要。无关紧要的是,双分割技术会计算上下铰链,具体取决于样本量,该铰链可能与中位数略有不同。重要的是,双分裂似乎是基于对中位数的连续估算。此估算值与实际中位数之间的任何变化都将导致铰链也发生变化。直观地讲,随着数据量的增加,这应该不是问题,但是这是需要分析的问题。
ub

不会直接估计四分位数会遇到类似的问题吗?直接估计会将数据点划分为比例。这会将元素划分为,然后采用那些“ 2”之一并将其拆分为。我不是理论家,是真的,但是总的来说,两者之间的差异最多不会在左边或右边有一个点,并且随着增加会收敛吗?是的,可以创建一种病理分布,但是这也会受到直接中值估计的影响。显然,存储所有值当然更好。1 3 2 2 1 1 nn1:32:21:1n
Avraham

2
@Avraham,感谢您指出本文,正如我提到的那样,我已经尝试使用Chain和Chlamtac的P平方算法。在我的数据集上,我描述的算法给出了更好的结果(MSE)并且更快。因此,我一直在质疑它是否还会出现问题。如胡布所说,它使用连续估算是一个潜在的问题; 但是我不知道它是否真的很重要。
Louis Hugues 2014年

哎呀,看到了却忘记了。我很抱歉。
Avraham

0

对您发布的方法进行了非常微小的更改,您可以计算任意百分比,而不必计算所有分位数。这是Python代码:

class RunningPercentile:
    def __init__(self, percentile=0.5, step=0.1):
        self.step = step
        self.step_up = 1.0 - percentile
        self.step_down = percentile
        self.x = None

    def push(self, observation):
        if self.x is None:
            self.x = observation
            return

        if self.x > observation:
            self.x -= self.step * self.step_up
        elif self.x < observation:
            self.x += self.step * self.step_down
        if abs(observation - self.x) < self.step:
            self.step /= 2.0

和一个例子:

import numpy as np
import matplotlib.pyplot as plt

distribution = np.random.normal
running_percentile = RunningPercentile(0.841)
observations = []
for _ in range(1000000):
    observation = distribution()
    running_percentile.push(observation)
    observations.append(observation)

plt.figure(figsize=(10, 3))
plt.hist(observations, bins=100)
plt.axvline(running_percentile.x, c='k')
plt.show()

具有1个STD百分位数的正态分布

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.