Gözlemleri saklamadan çeyreklerin çevrimiçi tahmini


13

Çeyrekleri (Q1, medyan ve Q3) büyük bir veri setinde gözlemleri saklamadan gerçek zamanlı olarak hesaplamam gerekiyor. İlk önce P kare algoritmasını (Jain / Chlamtac) denedim ama memnun kalmadım (biraz fazla cpu kullanımı ve en azından veri setimdeki hassasiyetle ikna olmadım).

Şimdi FAME algoritmasını ( Feldman / Shavitt ) medyanı anında tahmin etmek için kullanıyorum ve Q1 ve Q3'ü de hesaplamak için algoritmayı türetmeye çalışıyorum:

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

Devam etmek için, veri kümesini ikiye bölmek ve ardından Q1 ve Q3 için aynı algoritmayı yeniden kullanmak için anında elde edilen medyan M'yi kullanır.

Bu bir şekilde çalışıyor gibi gözüküyor ama gösteremiyorum (matematikçi değilim). Kusurlu mu? Soruna uyan herhangi bir öneri veya nihai diğer tekniği takdir ediyorum.

Yardımın için çok teşekkürler !

==== DÜZENLE =====

Bu tür sorularla ilgilenenler için, birkaç hafta sonra, nihayet sadece 100 değerlik bir rezervuar ile Rezervuar Örneklemesi kullanarak sonlandırdım ve çok tatmin edici sonuçlar verdi (bana).


Örneklerin sayısı, bağladığınız slaytlardaki markov zinciri analizine benzer bir şekilde arttıkça, Q1 ve Q2'nin gerçek miktarlara yakınlaştığına dair bir kanıt mı arıyorsunuz? Uygulama açısından, yukarıdaki algoritma kusurlu görünmüyor (R'de standart normal için yaklaşık miktarları test ettim ve algoritma iyi çalışıyor).
Theja

1
@Theja teşekkür ederim, bir kanıt (çok fazla iş) değil, sadece tavsiye ve yorum arıyorum, Gördüğüm temel sorun, whuber'ın işaret ettiği gibi, hesaplamayı medyan tahminine dayandırmaktır.
Louis Hugues

Yanıtlar:


3

Medyan, gözlemlerin 1 / 2'sinin altına ve 1 / 2'nin üzerine düştüğü noktadır. Benzer şekilde, 25. perecentil, min ve medyan arasındaki veriler için medyan ve 75. persentil medyan ve max arasındaki medyan, bu yüzden evet, ilk önce kullandığınız medyan algoritmayı uygulayarak sağlam bir zemindesiniz tüm veriyi bölümlere ayıracak ve sonuçta ortaya çıkan iki parça üzerinde olacaktır.

Güncelleme :

Stackoverflow ile ilgili bu soru şu makaleye yol açmaktadır: Raj Jain, Imrich Chlamtac: Gözlemleri Saklamaksızın Nicel ve Histogramların Dinamik Hesaplanması için P² Algoritması. Commun. ACM 28 (10): 1076-1085 (1985) , özeti muhtemelen sizi ilgilendirdiğini gösterir:

Medyan ve diğer niceliklerin dinamik hesaplanması için sezgisel algoritma önerilir. Gözlemler üretilirken tahminler dinamik olarak üretilir. Gözlemler saklanmaz; bu nedenle algoritmanın, gözlem sayısına bakılmaksızın çok küçük ve sabit bir depolama gereksinimi vardır. Bu, endüstriyel kontrolörlerde ve kayıt cihazlarında kullanılabilen bir kantil çipte uygulama için idealdir. Algoritma ayrıca histogram çizilmesine genişletilir. Algoritmanın doğruluğu analiz edilir.


4
Bu cevap, biri önemsiz fakat diğeri muhtemelen çok önemli olan iki ince noktaya bakmaktadır. Önemli olmayan, çift bölme tekniğinin , numune boyutlarına bağlı olarak, medyandan biraz farklı olabilen üst ve alt menteşeleri hesaplamasıdır . Önemli olan, çift bölmenin medyanın akan bir tahminine dayanıyor gibi görünmesidir . Bu tahmin ile gerçek ortanca arasındaki herhangi bir değişiklik, menteşelerin de değişmesine neden olacaktır. Sezgisel olarak, veri miktarı büyüdükçe bu bir sorun olmamalı, ancak biraz analiz gerektiren bir konudur.
whuber

Çeyrekleri doğrudan tahmin etmek benzer sorunlara maruz kalmaz mı? Doğrudan tahmin, veri noktasını oranına böler . Bu, elemanları böler ve sonra bu "2" lerden birini alır ve böler . Ben teorik değilim, doğru, ama genel olarak, ikisi arasındaki fark sola veya sağa en fazla bir nokta farklı olmaz ve arttıkça yakınlaşır mı? Evet, patolojik bir dağılım oluşturulabilir, ancak bu doğrudan medyan tahmininden de etkilenir. Tabii ki, tüm değerleri depolamak daha iyidir. 1 : 3 2 : 2 1 : 1 nn1:32:21:1n
Avraham

2
@Aavraham, gazeteyi işaret ettiğiniz için teşekkürler, daha önce de belirttiğim gibi Chain ve Chlamtac'tan P-kare algoritmasını denedim. Veri setimde beyan ettiğim algo daha iyi sonuç verir (MSE) ve daha hızlıdır. Yine de bunun bir problemi olup olmadığını sorguladım. Whuber'ın belirttiği gibi, tahmini bir tahmin kullandığı gerçeği potansiyel bir sorundur; ama gerçekten önemli olup olmadığını bilmiyorum.
Louis Hugues

Hata! Bunu gördüm ve unuttum. Özür dilerim.
Avraham

0

Gönderdiğiniz yöntemde çok küçük bir değişiklik ve tüm nicelikleri hesaplamak zorunda kalmadan herhangi bir rasgele persantil hesaplayabilirsiniz. İşte Python kodu:

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

ve bir örnek:

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 persentil ile Normal Dağılım

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.