İstatistiksel medyan, mod, çarpıklık, basıklık tahmin etmek için "çevrimiçi" (yineleyici) algoritmalar?


86

Değerler kümesinin medyanını, modunu, çarpıklığını ve / veya basıklığını tahmin etmek için bir algoritma var mı, ancak bu, tüm değerlerin aynı anda bellekte saklanmasını GEREKTİRMEZ?

Temel istatistikleri hesaplamak istiyorum:

  • ortalama: aritmetik ortalama
  • varyans: ortalamadan kare sapmaların ortalaması
  • standart sapma: varyansın karekökü
  • ortanca: sayıların büyük yarısını küçük yarısından ayıran değer
  • mod: sette bulunan en sık değer
  • çarpıklık: tl; dr
  • basıklık: tl; dr

Bunlardan herhangi birini hesaplamak için temel formüller ilkokul aritmetiğidir ve bunları biliyorum. Bunları uygulayan birçok istatistik kitaplığı da var.

Benim sorunum, ele aldığım kümelerdeki çok sayıda (milyarlarca) değer: Python'da çalışarak, milyarlarca öğeyle bir liste veya hash yapamam. Bunu C'de yazmış olsam bile, milyar elemanlı diziler çok pratik değil.

Veriler sıralanmamış. Diğer süreçler tarafından anında rastgele üretilir. Her setin boyutu oldukça değişkendir ve boyutları önceden bilinmeyecektir.

Kümedeki her bir değeri herhangi bir sırayla yineleyerek, ortalama ve varyansı nasıl çok iyi idare edeceğimi zaten buldum. (Aslında benim durumumda, onları oluşturuldukları sırayla alıyorum.) İşte kullandığım algoritma, http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm izniyle :

  • Üç değişkeni başlatın: count, sum ve sum_of_squares
  • Her değer için:
    • Artış sayısı.
    • Toplanacak değeri ekleyin.
    • Sum_of_squares'e değerin karesini ekleyin.
  • Toplamı sayıya bölün, değişken ortalama olarak saklayın.
  • Sum_of_squares öğesini sayıya bölerek, ortalama_kareler değişkeni olarak saklayın.
  • Ortalama karekök olarak saklanan kare ortalama.
  • Ortalama_karakterlerden ortalama_karesini çıkar, varyans olarak sakla.
  • Çıktı ortalaması ve varyans.

Bu "çevrimiçi" algoritmanın zayıf yönleri vardır (örneğin, sum_of_squares tamsayı aralığından veya kayan kesinlikten hızlı bir şekilde büyüdüğü için doğruluk sorunları), ancak temelde her bir kümedeki her değeri saklamak zorunda kalmadan ihtiyacım olanı verir.

Ancak, ek istatistikleri tahmin etmek için benzer tekniklerin var olup olmadığını bilmiyorum (medyan, mod, çarpıklık, basıklık). N değerlerini işlemek için gereken bellek önemli ölçüde O (N) 'den daha az olduğu sürece yanlı bir tahmin ediciyle veya hatta doğruluğu belirli bir dereceye kadar tehlikeye atan bir yöntemle yaşayabilirim.

Kitaplığın bu işlemlerden birini veya birkaçını "çevrimiçi" olarak hesaplamak için işlevleri varsa, beni mevcut bir istatistik kitaplığına yönlendirmek de yardımcı olacaktır.


veriler sıralı olarak aktarılacak mı ve girişlerin sayısını önceden bilecek misiniz?
chillysapien


Bu tamsayı veri mi yoksa kayan veri mi? Maksimum veya minimum değeriniz var mı?
stephan

dmckee: Aslında standart sapma için Welford Yöntemini kullanıyorum. Ama bu bağlantıda mod, medyan, basıklık veya çarpıklık hakkında hiçbir şey görmüyorum ... Bir şey mi kaçırıyorum?
Ryan B. Lynch

stephan: Bazı veri setleri tam sayıdır, diğerleri yüzerdir. Nüfus dağılımı normale oldukça yakındır (Gaussian), bu nedenle bir güven aralığı oluşturabiliriz, ancak kesin bir aralık sınırı yoktur (bazı durumlarda x> 0 hariç).
Ryan B. Lynch

Yanıtlar:


53

Çarpıklık ve Basıklık

Çarpıklık ve Basıklık için çevrimiçi algoritmalar (varyans çizgileri boyunca) için aynı wiki sayfasına bakın burada daha yüksek moment istatistikleri için paralel algoritmalar.

Medyan

Medyan, sıralı veriler olmadan zordur. Kaç tane veri noktasına sahip olduğunuzu biliyorsanız, teoride sadece kısmen sıralamanız gerekir, örneğin bir seçim algoritması kullanarak . Ancak bu milyarlarca değere pek yardımcı olmuyor. Sıklık sayımlarını kullanmanızı öneririm, sonraki bölüme bakın.

Medyan ve Frekans Sayımlı Mod

Tamsayı ise, frekansları sayardım , muhtemelen artık alakalı olmadığından emin olduğum bir değerin ötesinde en yüksek ve en düşük değerleri keserdim. Yüzer sayılar (veya çok fazla tam sayı) için, muhtemelen kovalar / aralıklar oluşturur ve ardından tamsayılarla aynı yaklaşımı kullanırdım. (Yaklaşık) modu ve medyan hesaplaması, frekanslar tablosuna göre kolaylaşır.

Normal Olarak Dağıtılan Rastgele Değişkenler

Normal olarak dağıtılırsa, küçük bir alt küme için maksimum olasılık tahmin edicileri olarak popülasyon örneklem ortalamasını , varyansı , çarpıklığı ve basıklığı kullanırdım . Bunları hesaplamak için (çevrimiçi) algoritmalar, zaten şimdi. Örneğin, tahmin hatanız yeterince küçük olana kadar birkaç yüz bin veya milyon veri noktasını okuyun. Kümenizden rastgele seçim yaptığınızdan emin olun (örneğin, ilk 100'000 değeri seçerek bir önyargı oluşturmadığınızdan). Aynı yaklaşım, tahmin modu ve normal durum için medyan için de kullanılabilir (her iki örneklem ortalaması için bir tahmin edicidir).

Ek yorumlar

Yardımcı olursa yukarıdaki tüm algoritmalar paralel olarak çalıştırılabilir (birçok sıralama ve seçim algoritması, örneğin QuickSort ve QuickSelect dahil).

Her zaman (normal dağılımla ilgili bölüm hariç) örnek momentler, medyan ve mod hakkında konuştuğumuzu varsaydım, bilinen bir dağılım verildiğinde teorik momentler için tahmin edicilerden değil.

Genel olarak, tüm gözlemler aynı rasgele değişkenin (aynı dağılımlara sahip olan) ve anların, modun ve anların, modun ve ortanca aslında bu dağılım için mevcuttur. Son uyarı zararsız değildir. Örneğin, Cauchy Dağılımı için ortalama (ve tüm yüksek anlar) mevcut değildir. Bu durumda, "küçük" bir alt kümenin örnek ortalaması, tüm örneğin örnek ortalamasından büyük ölçüde farklı olabilir.


57

Her ikisi de sabit depolama kullanan bu artımlı / yinelemeli ortalama ve medyan tahmin edicileri kullanıyorum:

mean += eta * (sample - mean)
median += eta * sgn(sample - median)

burada eta , küçük bir öğrenme hızı parametresidir (örn. 0.001) ve sgn (), {-1, 0, 1} 'den birini döndüren işaret fonksiyonudur. ( Veriler sabit değilse ve zaman içindeki değişiklikleri izlemek istiyorsanız sabit bir eta kullanın ; aksi takdirde, sabit kaynaklar için ortalama tahminci için eta = 1 / n gibi bir şey kullanabilirsiniz ; burada n, bu şekilde görülen örnek sayısıdır. çok ... ne yazık ki, bu medyan tahmin edicisi için işe yaramıyor gibi görünüyor.)

Bu tür artımlı ortalama tahmin edicisi her yerde, örneğin denetimsiz sinir ağı öğrenme kurallarında kullanılıyor gibi görünmektedir, ancak medyan versiyonu, faydalarına rağmen (aykırı değerlere dayanıklılık) çok daha az yaygın görünmektedir. Görünüşe göre medyan versiyonu, birçok uygulamada ortalama tahmin edicinin yerine kullanılabilir.

Benzer bir formun artımlı mod tahmin edicisini görmeyi çok isterim ...

GÜNCELLEME

Artımlı medyan tahmin ediciyi rastgele nicelikleri tahmin etmek için değiştirdim. Genel olarak, bir nicelik işlevi ( http://en.wikipedia.org/wiki/Quantile_function ), verileri iki kesire bölen değeri size söyler: p ve 1-p. Aşağıdaki, bu değeri aşamalı olarak tahmin etmektedir:

quantile += eta * (sgn(sample - quantile) + 2.0 * p - 1.0)

P değeri [0,1] içinde olmalıdır. Bu, esasen sgn () işlevinin simetrik çıktısını {-1,0,1} bir tarafa doğru kaydırarak veri örneklerini eşit olmayan boyutlu iki bölmeye ayırır (verilerin p ve 1-p'si küçük / büyüktür) nicelik tahmini). P = 0.5 için bunun medyan tahmin ediciye indirgendiğine dikkat edin.


3
Bu medyan tahmin aracı harika. 0.25 / 0.75 kuantilleri için benzer tahmin ediciler olup olmadığını biliyor musunuz?
Gacek

1
@Gacek, elbette: Giriş akışını Lohalf <medyan ve Hihalf> medyana bölün ve her iki yarıda koşu medyanı kullanın.
denis

2
@Gacek: Yanıtımı, herhangi bir niceliği tahmin etmek için artımlı bir yöntemle güncelledim, burada p'yi 0,25, 0,75 veya [0,1] içindeki herhangi bir değere ayarlayabilirsiniz .
Tyler Streeter'un

10
Bu ortalama için harika çalışıyor, ancak medyana uzaktan yakın bir şeyi nasıl ürettiğini görmüyorum. Örneğin [1328083200000, 981014400000, -628444800000, 318240000000, 949392000000], medyanı olan bir milisaniye zaman damgası dizisi alın 318240000000. Bu denklem eta, önerilen değerin +/- olduğu önceki medyanı değiştirir 0.001. Bu, bunun gibi büyük sayılar için hiçbir şey yapmaz ve gerçekten küçük sayılar için çok büyük olabilir. etaCevabı a priori bilmeden, size gerçekten doğru cevabı veren bir şeyi nasıl seçerdiniz ?
mckamey

9
Sayıların birimleri, örneğin milimetre olduğunu hayal edin. Öyleyse açık bir şekilde eta (medyanın tahmini için) ölçümlerle aynı birimlere sahip olmalıdır ve bu nedenle 0.001 gibi genel bir değer hiçbir anlam ifade etmez. Görünüşte daha iyi bir yaklaşım, eta'yı mutlak sapmanın çalışan bir tahmininden ayarlamaktır: her yeni değer için samplegüncelleme cumadev += abs(sample-median). Ardından eta = 1.5*cumadev/(k*k), kşimdiye kadar görülen örneklerin sayısını ayarlayın .
tholy

12

Ben hayata Gözlemleri saklanması olmadan P-Kare Algoritması kantilleri ve Histogramlar Dinamik Hesaplama aradım yazdım düzgün bir Python modülü LiveStats . Sorununuzu oldukça etkili bir şekilde çözmelidir. Kütüphane, mod dışında bahsettiğiniz her istatistiği destekler. Henüz mod tahmini için tatmin edici bir çözüm bulamadım.


Bilginize: p-kare algoritması C ++ boost şöyledir: <boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp>.
Neil G

7

Ryan, korkarım ortalama ve varyansı doğru yapmıyorsun ... Bu, birkaç hafta önce burada ortaya çıktı . Ve çevrimiçi versiyonu güçlü noktalarından biri (aslında Welford yöntemi adıyla gider) özel olarak doğru ve istikrarlı olduğunu gerçektir, tartışmaya bakınız burada . Güçlü noktalardan biri, toplam kareyi veya toplam kareleri depolamanıza gerek olmamasıdır ...

Tüm listeyi aynı anda düşünmeyi gerektiren mod ve medyan için herhangi bir çevrimiçi yaklaşım düşünemiyorum. Ancak, varyans ve ortalama için olana benzer bir yaklaşım, çarpıklık ve basıklık için de işe yarayabilir ...


re: skewness and kurtosisEvet. Bu makaleye bakın: johndcook.com/blog/skewness_kurtosis
Jesse Chisholm

3

Soruda alıntılanan Wikipedia makalesi, çarpıklığı ve basıklığı çevrimiçi olarak hesaplamanın formüllerini içerir.

Mod için - inanıyorum ki - bunu çevrimiçi yapmanın bir yolu yok. Neden? Girişinizin tüm değerlerinin bir öncekini çoğaltan sonuncunun yanı sıra farklı olduğunu varsayalım. Bu durumda, son değerin önceden görülen bir değeri çoğalttığını ve onu en sık olanı yaptığını tespit etmek için girdide önceden görülen tüm değerleri hatırlamanız gerekir.

Medyan için neredeyse aynıdır - son girişe kadar, tüm giriş değerleri farklıysa hangi değerin medyan olacağını bilemezsiniz çünkü mevcut medyandan önce veya sonra olabilir. Girişin uzunluğunu biliyorsanız, medyanı tüm değerleri hafızaya kaydetmeden bulabilirsiniz, ancak yine de birçoğunu saklamanız gerekecektir (sanırım yarısı civarında) çünkü kötü bir giriş dizisi medyanı büyük ölçüde kaydırabilir. ikinci yarı muhtemelen medyanın ilk yarısından herhangi bir değer alır.

(Yalnızca kesin hesaplamaya değindiğimi unutmayın.)


2

Milyarlarca veri noktanız varsa, yakın yanıtların aksine kesin yanıtlara ihtiyacınız yoktur. Genel olarak, milyarlarca veri noktasına sahipseniz, bunları oluşturan temel süreç muhtemelen bir tür istatistiksel durağanlık / ergodiklik / karıştırma özelliğine uyacaktır. Ayrıca, dağıtımların makul ölçüde sürekli olmasını bekleyip beklemediğiniz önemli olabilir.

Bu durumlarda, çevrimiçi, düşük bellek, kuantillerin tahmini (medyan, 0.5 kuantillik özel bir durumdur) ve ayrıca tam yanıtlara ihtiyacınız yoksa modlar için algoritmalar vardır . Bu aktif bir istatistik alanıdır.

nicel tahmin örneği: http://www.computer.org/portal/web/csdl/doi/10.1109/WSC.2006.323014

mod tahmin örneği: Bickel DR. Sürekli verilerin mod ve çarpıklığının sağlam tahmin edicileri. Hesaplamalı İstatistikler ve Veri Analizi. 2002; 39: 153–163. doi: 10.1016 / S0167-9473 (01) 00057-3.

Bunlar hesaplama istatistiğinin aktif alanlarıdır. Tek bir en iyi kesin algoritmanın olmadığı, ancak bunların farklı özelliklere, varsayımlara ve performansa sahip bir çeşitliliğinin (gerçekte istatistiksel tahmin ediciler) olduğu alanlara giriyorsunuz. Deneysel matematik. Konuyla ilgili muhtemelen yüzlerce ila binlerce makale var.

Son soru, çarpıklığa ve basıklığa gerçekten ihtiyacınız olup olmadığıdır, yoksa olasılık dağılımını karakterize etmede daha güvenilir olabilecek bazı diğer parametrelere (olasılık dağılımına sahip olduğunuzu varsayarsak!). Bir Gauss'lu mu bekliyorsunuz?

Verileri çoğunlukla Gaussian yapmak için temizleme / ön işleme yöntemleriniz var mı? (örneğin, finansal işlem tutarları, logaritma alındıktan sonra genellikle biraz Gauss şeklindedir). Sonlu standart sapmalar bekliyor musunuz? Şişman kuyruklar bekliyor musunuz? Önem verdiğiniz miktarlar kuyruklarda mı yoksa toplu olarak mı?


2

Herkes modu çevrimiçi bir şekilde yapamayacağınızı söyleyip duruyor, ancak bu kesinlikle doğru değil. İşte 1982'de Yale Üniversitesi'nden Michael E. Fischer ve Steven L. Salzberg tarafından icat edilen tam da bu problemi yapmak için bir algoritmayı açıklayan bir makale . Makaleden:

Çoğunluk bulma algoritması, akıştan tek bir öğenin geçici olarak depolanması için kendi kayıtlarından birini kullanır; bu öğe, çoğunluk unsuru için mevcut adaydır. İkinci kayıt, 0'a başlatılan bir sayaçtır. Akışın her bir öğesi için, algoritmadan aşağıdaki rutini gerçekleştirmesini isteriz. Sayaç 0 okursa, mevcut akış elemanını yeni çoğunluk adayı olarak kurun (halihazırda kayıt defterinde bulunabilecek herhangi bir başka elemanın yerini alarak). Ardından, mevcut öğe çoğunluk adayıyla eşleşirse, sayacı artırın; aksi takdirde sayacı azaltın. Döngünün bu noktasında, akışın şimdiye kadar görülen kısmı çoğunluk elemanına sahipse, bu eleman aday kayıtçısındadır ve sayaç 0'dan büyük bir değere sahiptir. Ya çoğunluk unsuru yoksa? Veri üzerinden ikinci bir geçiş yapmadan - ki bu bir akış ortamında mümkün değildir - bu durumda algoritma her zaman kesin bir cevap veremez. Yalnızca, varsa çoğunluk unsurunu doğru bir şekilde tanımlamayı vaat ediyor.

Ayrıca daha fazla belleğe sahip ilk N'yi bulmak için genişletilebilir, ancak bu mod için onu çözmelidir.


4
Bu ilginç bir algoritmadır, ancak bir şeyi kaçırmazsam, tüm çoğunluk değerleri mod olurken, tüm modlar çoğunluk değerleri olmayacaktır.
jkebinger

Bağlantı öldü, bu yüzden açıklamanın dahil edilmesine sevindim. ANCAK, açıklandığı gibi, sayaç yalnızca çoğunluk aday 2. oluşum 1. oluşumla bitişikse artar. Hangi IMPLIES verileri sıraladı. Çevrimiçi (akışlı) veri durumunda garanti EDİLMEZ. Rastgele sıralanan verilerle, bu herhangi bir mod bulması olası değildir.
Jesse Chisholm

1

Nihayetinde, dağılımla ilgili önceden parametrik bilginiz yoksa, tüm değerleri kaydetmeniz gerektiğini düşünüyorum.

Bununla birlikte, bir tür patolojik durumla uğraşmadığınız sürece, çare (Rousseuw ve Bassett 1990) amaçlarınız için yeterince iyi olabilir.

Çok basit bir şekilde medyan gruplarının medyanını hesaplamayı içerir.


0

medyan ve mod, yalnızca mevcut sabit alan kullanılarak çevrimiçi olarak hesaplanamaz. Bununla birlikte, medyan ve mod zaten "nicel" den daha "açıklayıcı" olduğundan, bunları örneğin veri setini örnekleyerek tahmin edebilirsiniz.

Veriler uzun vadede normal dağılıyorsa, medyanı tahmin etmek için sadece ortalamanızı kullanabilirsiniz.

Aşağıdaki tekniği kullanarak medyan da tahmin edebilirsiniz: veri akışındaki her 1.000.000 giriş için bir medyan tahmini M [i] oluşturun, böylece M [0] ilk bir milyon girişin medyanı olur, M [1] ikinci bir milyon girişin medyanı vb. Ardından medyan tahmin aracı olarak M [0] ... M [k] medyanını kullanın. Bu elbette yerden tasarruf sağlar ve 1.000.000 parametresini "ayarlayarak" alanı ne kadar kullanmak istediğinizi kontrol edebilirsiniz. Bu aynı zamanda özyinelemeli olarak genelleştirilebilir.


0

Tamam ahbap şunları dene:

c ++ için:

double skew(double* v, unsigned long n){
    double sigma = pow(svar(v, n), 0.5);
    double mu = avg(v, n);

    double* t;
    t = new double[n];

    for(unsigned long i = 0; i < n; ++i){
        t[i] = pow((v[i] - mu)/sigma, 3);
    }

    double ret = avg(t, n);

    delete [] t;
    return ret;
}

double kurt(double* v, double n){
    double sigma = pow(svar(v, n), 0.5);
    double mu = avg(v, n);

    double* t;
    t = new double[n];

    for(unsigned long i = 0; i < n; ++i){
        t[i] = pow( ((v[i] - mu[i]) / sigma) , 4) - 3;
    }

    double ret = avg(t, n);

    delete [] t;
    return ret;
}

Zaten örnek varyansını (svar) ve ortalamayı (ortalama) hesaplayabileceğinizi söylediğinizde, bunları yapmak için işlevlerinize yönlendirirsiniz.

Ayrıca, Pearson'un yaklaşımı meselesine bir bakın. böylesine büyük bir veri kümesinde oldukça benzer olacaktır. 3 (ortalama - medyan) / standart sapma maksimum - min / 2 olarak medyanınız var

yüzer modunun anlamı yoktur. tipik olarak bunları sginificant boyutundaki kutulara yapıştırır (1/100 * (maks - min) gibi).



-1

Uyarlanabilir olabilen kovalar kullanma eğilimindeyim. Kova boyutu, ihtiyacınız olan doğrulukta olmalıdır. Daha sonra, her veri noktası geldiğinde, ilgili bölümün sayısına bir tane eklersiniz. Bunlar, her bir kepçeyi kendi sayısına göre ağırlıklandırılmış bir değer olarak sayarak, medyan ve basıklık için basit tahminler vermelidir.

Tek sorun, milyarlarca işlemden sonra kayan noktada çözünürlük kaybı olabilir, yani bir tane eklemek artık değeri değiştirmez! Bunu aşmak için, maksimum kepçe boyutu bir sınırı aşarsa, tüm sayılardan büyük bir sayı alabilirsiniz.


-1
for j in range (1,M):
    y=np.zeros(M) # build the vector y
    y[0]=y0

    #generate the white noise
    eps=npr.randn(M-1)*np.sqrt(var)

    #increment the y vector
    for k in range(1,T):
        y[k]=corr*y[k-1]+eps[k-1]

    yy[j]=y

list.append(y)

Bunu orijinal soruya daha iyi bağlamak için biraz açıklama kullanabiliriz.
Erica
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.