Büyük bir defalarca okunan veri kümesinin ortancasını tahmin etmek için iyi bir algoritma nedir?


47

Saklamak için çok büyük bir veri kümesinin ortancasını tahmin etmek için iyi bir algoritma (en az hesaplama, en az depolama gereksinimleri anlamına gelir) arıyorum, öyle ki her bir değer yalnızca bir kez okunabilir (bu değeri açıkça saklayamazsanız). Varsayılabilecek verilerde sınır yoktur.

Doğruluğu bilindiği sürece, yaklaşımlar iyidir.

Herhangi bir işaretçi var mı?


4
Belki de Stackoverflow'u sormak daha iyi cevaplar alabilir.

2
@Srikant:> istatistikte oldukça aktif bir araştırma alanıdır :) Depolama açısından daha düşük teorik sınırlara en yakın olan çözüm, bazı akıllıca olasılık yapıları da içerir. Sonuçta birkaç ay önce ilk kez baktığımda şaşırdım; burada göründüğünden daha fazla istatistik var.
user603

Yanıtlar:


6

Veri kümesini çok daha küçük veri kümeleri halinde gruplandırabilir misiniz (100 veya 1000 veya 10.000 veri noktası demek). O zaman grupların her birinin medyanını hesapladıysanız. Bunu yeterli veri kümeleriyle yaptıysanız, daha küçük kümelerin her birinin sonuçlarının ortalaması gibi bir şey çizebilir ve yeterince küçük veri kümeleri çalıştırarak, 'ortalama' bir çözüme yaklaşır.


Bu ilginç ve bazı istatistiksel tavsiyelerin alınabileceği bir yer! Toplam olarak 500.000 iid puanım olduğunu ve 1000'inin (di) gruplarına bakıp her grubun medyanını hesapladığımı varsayalım. Şimdi 500 ortancım var. Bu ortancaya dayanan genel ortanca için bir güven aralığı hesaplamama izin verecek bir teori var mı?
PeterR,

4
Yani, uzun süredir kaybedilen bir meslektaşına göre, en iyi yaklaşım, Chiranjeeb Buragohain ve Subhash Suri gibi görünüyor. Akarsu Üzerindeki Kuaförler. cs.ucsb.edu/~suri/psdir/ency.pdf Ian'ın yaklaşımını da seviyorum, çünkü daha küçük veri kümelerinin ortancaları normal dağılıma yaklaşacak ve bu yüzden medyanlar için kendi aralıkları oluşturabilirim.
PeterR,

9

Bir binicilik prosedürü gibi bir şey hakkında nasıl? (Gösterim amacıyla) değerlerin 1 ile 1 milyon arasında olduğunu bildiğinizi varsayalım. S boyutunda N kutu ayarlayın. Öyleyse S = 10000 ise, [1: 10000, 10001: 20000, ..., 990001: 1000000] değerlerine karşılık gelen 100 kutuya sahip olursunuz.

Ardından, değerler arasında ilerleyin. Her değeri saklamak yerine, sayacı uygun kutuya artırın. Her bir bölmenin orta noktasını bir tahmin olarak kullanarak, medyanın makul bir yaklaşımını yapabilirsiniz. Kutuların boyutunu değiştirerek, istediğiniz kadar ince veya kaba bir çözünürlüğe ölçeklendirebilirsiniz. Sadece ne kadar hafızanız olduğu ile sınırlısınız.

Değerlerinizin ne kadar büyük olabileceğini bilmediğiniz için, bazı hızlı geri dönüş hesaplamaları kullanarak bellek tükenmeyecek kadar büyük bir kutu boyutu seçin. Kutuları seyrek de saklayabilirsiniz, böylece yalnızca bir değer içeriyorsa bir çöp kutusu eklersiniz.

Düzenle:

Link ryfm, sadece orta noktaları kullanmak yerine medyan kutusundaki noktayı daha doğru bir şekilde tahmin etmek için kümülatif yüzdeleri kullanma ek adımıyla bunu yapmanın bir örneğini sunar. Bu güzel bir gelişme.


Kutu alma yaklaşımındaki sorun, veriler için iyi bir üst sınırımız olmaması ve bu nedenle en büyük depo gözünün orta noktasının çok büyük olması gerektiğidir. Bu yüzden, çok sayıda kutuya (bunun için yeterli hafızaya sahip olmamaya) ya da oldukça geniş kutulara (daha sonra oldukça yanlış bir cevaba yol açacak) ihtiyacımız var. Veriler çok seyrek değil.
PeterR,

Sadece medyanla ilgilendiğiniz için, neden çöp kutularını değişkeninizin yüksek değerlerinde daha geniş hale getiremediniz?
russellpierce

drknexus - çünkü en büyük çöp kutusunun ne olması gerektiğini bilmiyoruz.
PeterR,

Poligonun ne olacağı konusunda herhangi bir sezginiz var mı? Cevapların yarısından fazlasının N sayısının altında olacağından eminseniz, son çöp kutunuzu istediğiniz kadar büyük yapabilirsiniz. Belki de son çöp kutunuz 1 trilyondan daha büyük sayılardır - bu yeterli olabilir mi? Modern sistemlerdeki bellek miktarı ile çok sayıda çöp kutusu depolayabilir ve oldukça yüksek çözünürlük elde edebilirsiniz. Veri yapıları bakımından, burada yoğun bir şekilde süslü ve hafızadan bahsetmiyoruz.
chrisamiller

Herhangi bir sezgi? Evet. Ve yaklaşımınız genel olarak işe yarayabilir. Ancak bu durumda çok fazla bellek / hesaplama yapamıyoruz. Cihazın saniyede onbinlerce öğe görebildiği ve bu amaç için ÇOK işlem yapamadığı bir ağ uygulamasındadır. İdeal / tipik senaryo değil, biliyorum ama ilginç kılan şey bu!
PeterR,


8

Rivest-Tarjan-Seçim algoritması herhangi sıralama olmadan lineer zamanlı olarak medyan eleman hesaplamak izin verir (bazen de medyan-of-medyan algoritması olarak adlandırılır). Büyük veri kümeleri için bu, log-linear sıralamadan biraz daha hızlı olabilir. Ancak, bellek depolama probleminizi çözmez.



2

Bunu yapmak zorunda kalmamıştım, bu sadece bir öneri.

İki (diğer) olasılık görüyorum.

Yarı veri

  1. Verilerin yarısını yükle ve sırala
  2. Daha sonra kalan değerleri okuyun ve sıraladığınız listeyle karşılaştırın.
    1. Yeni değer daha büyükse, atın.
    2. aksi halde değeri sıralanan listeye koyun ve en büyük değeri bu listeden kaldırın.

Örnekleme dağılımı

Diğer seçenek, örnekleme dağılımını içeren bir yaklaşım kullanmaktır. Verileriniz Normal ise, orta n için standart hata şudur:

1,253 * sd / sqrt (n)

Memnun kalacağınız n sayısını belirlemek için , R'de hızlı bir Monte-Carlo simülasyonu kullandım.

n = 10000
outside.ci.uni = 0
outside.ci.nor = 0
N=1000
for(i in 1:N){
  #Theoretical median is 0
  uni = runif(n, -10, 10)
  nor  = rnorm(n, 0, 10)

  if(abs(median(uni)) > 1.96*1.253*sd(uni)/sqrt(n))
    outside.ci.uni = outside.ci.uni + 1

  if(abs(median(nor)) > 1.96*1.253*sd(nor)/sqrt(n))
    outside.ci.nor = outside.ci.nor + 1
}

outside.ci.uni/N
outside.ci.nor/N

N = 10000 için, tek tip medyan tahminlerinin% 15'i CI dışındaydı.


3
Veri seti, yarısı kadar okumak için potansiyel olarak çok büyük ... bir işlem bağlamında, işlem yapan cihazın saniyede on binlerce öğeyi görebildiği ve muhtemelen yalnızca birkaç yüz saklamak için yeterli belleğe sahip olduğu bir ağ bağlamında. Ayrıca veriler kesinlikle Gauss değil. Aslında, ortak dağıtımların hiçbirine iyi uymuyor.
PeterR,


1

İşte stackoverflow'ta sorulan soruya bir cevap: https://stackoverflow.com/questions/1058813/on-line-iterator-algorithms-for-estimating-statistical-median-mode-skewness/2144754#2144754

Yinelemeli güncelleme ortanca + = eta * sgn (ornek - ortanca) bir yol gibi görünebilir.


1
ama sonra eta nasıl seçilir ve bunun istatistiksel olarak anlamı nedir? yani bu sonuçtan medyan için güven aralıkları nasıl oluşturulur?
PeterR,

@PeterR, hey, kullandığınız son çözüm nedir?
Aakash Goel

1

Remedian Algoritması (PDF) düşük depolama gereksinimleri ve iyi tanımlanmış doğrulukta bir tek-geçiş medyan tahminini verir.

Baz b olan iyileştirici, b gözlem gruplarının ortancalarını hesaplayarak ilerler ve sonra bu medyanların ortancalarını, yalnızca bir tahmin kalıncaya kadar hesaplar. Bu yöntem yalnızca b boyutunda k dizilerine ihtiyaç duyar (burada n = b ^ k) ...


1

Eğer değerler kullandığınız belirli bir aralık içinde olan, verimli (BSD alınan bu kod ea lisanslı bir tamsayı kova ile, değerler (söz hakkından, girişlerin trilyonlarca) son derece çok sayıda medyan hesaplayabilir, 100000 1 say -utils / sam-stats.cpp)

class ibucket {
public:
    int tot;
    vector<int> dat;
    ibucket(int max) {dat.resize(max+1);tot=0;}
    int size() const {return tot;};

    int operator[] (int n) const {
        assert(n < size());
        int i;
        for (i=0;i<dat.size();++i) {
            if (n < dat[i]) {
                return i;
            }
            n-=dat[i];
        }
    }

    void push(int v) {
        assert(v<dat.size());
        ++dat[v];
        ++tot;
    }
};


template <class vtype>
double quantile(const vtype &vec, double p) {
        int l = vec.size();
        if (!l) return 0;
        double t = ((double)l-1)*p;
        int it = (int) t;
        int v=vec[it];
        if (t > (double)it) {
                return (v + (t-it) * (vec[it+1] - v));
        } else {
                return v;
        }
}

Ayrıca, bu, gerçek zamanlı medyanlar, vb. İçin sınırlı sayıda kutu kullanmaya da genişletilebilir.
Erik Aronesty,
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.