Algoritme "On-line" (iterator) untuk memperkirakan median statistik, mode, skewness, kurtosis?

86

Apakah ada algoritme untuk memperkirakan median, mode, kemiringan, dan / atau kurtosis dari kumpulan nilai, tetapi itu TIDAK mengharuskan penyimpanan semua nilai dalam memori sekaligus?

Saya ingin menghitung statistik dasar:

  • mean: rata-rata aritmatika
  • varians: rata-rata deviasi kuadrat dari mean
  • deviasi standar: akar kuadrat dari varians
  • median: nilai yang memisahkan setengah angka yang lebih besar dari setengah angka yang lebih kecil
  • mode: nilai paling sering ditemukan di set
  • kemiringan: tl; dr
  • kurtosis: tl; dr

Rumus dasar untuk menghitung semua ini adalah aritmatika sekolah dasar, dan saya memang mengetahuinya. Ada banyak pustaka statistik yang menerapkannya juga.

Masalah saya adalah banyaknya (miliaran) nilai dalam set yang saya tangani: Bekerja dengan Python, saya tidak bisa hanya membuat daftar atau hash dengan miliaran elemen. Bahkan jika saya menulis ini dalam C, array miliar elemen tidak terlalu praktis.

Data tidak diurutkan. Ini diproduksi secara acak, dengan cepat, oleh proses lain. Ukuran setiap set sangat bervariasi, dan ukurannya tidak akan diketahui sebelumnya.

Saya sudah menemukan cara menangani mean dan varians dengan cukup baik, mengulangi setiap nilai dalam set dalam urutan apa pun. (Sebenarnya, dalam kasus saya, saya mengambilnya sesuai urutan pembuatannya.) Berikut adalah algoritme yang saya gunakan, dengan izin http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm :

  • Inisialisasi tiga variabel: count, sum, dan sum_of_squares
  • Untuk setiap nilai:
    • Hitungan kenaikan.
    • Tambahkan nilai untuk menjumlahkan.
    • Tambahkan kuadrat dari nilai tersebut ke sum_of_squares.
  • Bagilah jumlah dengan hitungan, simpan sebagai rata-rata variabel.
  • Bagilah sum_of_squares dengan hitungan, simpan sebagai variabel mean_of_squares.
  • Rata-rata persegi, menyimpan sebagai square_of_mean.
  • Kurangi square_of_mean dari mean_of_squares, simpan sebagai varians.
  • Rata-rata keluaran dan varians.

Algoritme "on-line" ini memiliki kelemahan (misalnya, masalah akurasi karena sum_of_squares dengan cepat tumbuh lebih besar dari kisaran integer atau presisi float), tetapi pada dasarnya memberikan apa yang saya butuhkan, tanpa harus menyimpan setiap nilai di setiap set.

Tapi saya tidak tahu apakah ada teknik serupa untuk memperkirakan statistik tambahan (median, mode, skewness, kurtosis). Saya bisa hidup dengan estimator bias, atau bahkan metode yang membahayakan akurasi sampai tingkat tertentu, selama memori yang dibutuhkan untuk memproses nilai N secara substansial kurang dari O (N).

Mengarahkan saya ke pustaka statistik yang ada juga akan membantu, jika pustaka tersebut memiliki fungsi untuk menghitung satu atau lebih operasi ini "on-line".

Ryan B. Lynch
sumber
Akankah data yang dikirimkan akan disortir, dan apakah Anda akan mengetahui sebelumnya jumlah inputnya?
chillysapien
Tautan berguna yang ada di StackOverflow: stackoverflow.com/questions/895929/…
dmckee --- mantan moderator kucing
Apakah itu data integer atau data float? Apakah Anda memiliki nilai maks atau min?
stephan
dmckee: Saya sebenarnya menggunakan Metode Welford untuk deviasi standar. Tapi saya tidak melihat apa pun di tautan itu tentang mode, median, kurtosis, atau skewness ... Apakah saya melewatkan sesuatu?
Ryan B. Lynch
stephan: Beberapa kumpulan data adalah bilangan bulat, yang lainnya adalah float. Distribusi populasi cukup dekat dengan normal (Gaussian), sehingga kita dapat menetapkan interval kepercayaan, tetapi tidak ada batasan rentang tegas (kecuali x> 0, dalam beberapa kasus).
Ryan B. Lynch

Jawaban:

53

Skewness dan Kurtosis

Untuk algoritma on-line untuk Skewness dan Kurtosis (sepanjang garis varians), lihat di halaman wiki yang sama di sini algoritma paralel untuk statistik momen yang lebih tinggi.

Median

Median sulit tanpa data yang diurutkan. Jika Anda tahu, berapa banyak poin data yang Anda miliki, secara teori Anda hanya perlu mengurutkan sebagian, misalnya dengan menggunakan algoritma pemilihan . Namun, itu tidak terlalu membantu dengan miliaran nilai. Saya akan menyarankan menggunakan hitungan frekuensi, lihat bagian selanjutnya.

Median dan Mode dengan Hitungan Frekuensi

Jika bilangan bulat, saya akan menghitung frekuensi , mungkin memotong nilai tertinggi dan terendah di luar beberapa nilai yang saya yakin tidak lagi relevan. Untuk pelampung (atau terlalu banyak bilangan bulat), saya mungkin akan membuat ember / interval, dan kemudian menggunakan pendekatan yang sama seperti untuk bilangan bulat. Mode (Perkiraan) dan perhitungan median menjadi mudah, berdasarkan tabel frekuensi.

Variabel Acak Terdistribusi Biasanya

Jika terdistribusi normal, saya akan menggunakan mean sampel populasi , varians , skewness , dan kurtosis sebagai penduga kemungkinan maksimum untuk subset kecil. Algoritme (on-line) untuk menghitungnya, Anda sudah sekarang. Misalnya membaca dalam beberapa ratus ribu atau juta titik data, hingga kesalahan estimasi Anda menjadi cukup kecil. Pastikan Anda memilih secara acak dari set Anda (mis. Anda tidak menimbulkan bias dengan memilih 100'000 nilai pertama). Pendekatan yang sama juga dapat digunakan untuk mode estimasi dan median untuk kasus normal (untuk kedua mean sampel adalah estimator).

Komentar lebih lanjut

Semua algoritme di atas dapat dijalankan secara paralel (termasuk banyak algoritme pengurutan dan pemilihan, misalnya QuickSort dan QuickSelect), jika ini membantu.

Saya selalu berasumsi (dengan pengecualian bagian tentang distribusi normal) bahwa kita berbicara tentang momen sampel, median, dan mode, bukan penduga untuk momen teoretis yang diberi distribusi yang diketahui.

Secara umum, pengambilan sampel data (yaitu hanya melihat sub-set) seharusnya cukup berhasil mengingat jumlah data, selama semua pengamatan adalah realisasi dari variabel acak yang sama (memiliki distribusi yang sama) dan momen, mode, dan median sebenarnya ada untuk distribusi ini. Peringatan terakhir bukannya tidak berbahaya. Misalnya, mean (dan semua momen yang lebih tinggi) untuk Distribusi Cauchy tidak ada. Dalam kasus ini, rata-rata sampel dari sub-set "kecil" mungkin jauh dari rata-rata sampel dari seluruh sampel.

stephan
sumber
57

Saya menggunakan penaksir rata-rata dan median inkremental / rekursif ini, yang keduanya menggunakan penyimpanan konstan:

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

di mana eta adalah parameter kecepatan pembelajaran kecil (misalnya 0,001), dan sgn () adalah fungsi signum yang mengembalikan salah satu dari {-1, 0, 1}. (Gunakan konstanta eta jika datanya tidak stasioner dan Anda ingin melacak perubahan dari waktu ke waktu; jika tidak, untuk sumber stasioner Anda dapat menggunakan sesuatu seperti eta = 1 / n untuk penduga rata-rata, dengan n adalah jumlah sampel yang terlihat begitu jauh ... sayangnya, ini tampaknya tidak berfungsi untuk penaksir median.)

Jenis penaksir rata-rata inkremental ini tampaknya digunakan di semua tempat, misalnya dalam aturan pembelajaran jaringan saraf yang tidak diawasi, tetapi versi median tampaknya jauh lebih umum, terlepas dari manfaatnya (ketahanan terhadap pencilan). Tampaknya versi median dapat digunakan sebagai pengganti penaksir rata-rata dalam banyak aplikasi.

Saya ingin melihat penaksir mode inkremental dengan bentuk serupa ...

MEMPERBARUI

Saya baru saja memodifikasi penaksir median tambahan untuk memperkirakan jumlah acak. Secara umum, fungsi kuantil ( http://en.wikipedia.org/wiki/Quantile_function ) memberi tahu Anda nilai yang membagi data menjadi dua pecahan: p dan 1-p. Berikut ini memperkirakan nilai ini secara bertahap:

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

Nilai p harus berada dalam [0,1]. Ini pada dasarnya menggeser keluaran simetris fungsi sgn () {-1,0,1} untuk condong ke satu sisi, mempartisi sampel data menjadi dua bin berukuran tidak sama (pecahan p dan 1-p data kurang dari / lebih besar dari perkiraan kuantitatif, masing-masing). Perhatikan bahwa untuk p = 0,5, ini mengurangi penduga median.

Tyler Streeter
sumber
3
Estimator median ini bagus. Apakah Anda tahu jika ada penduga yang serupa untuk 0,25 / 0,75 kuantil?
Gacek
1
@Gacek, tentu: bagi aliran input menjadi median Lohalf <median dan Hihalf>, dan gunakan running-median di setiap setengah.
denis
2
@Gacek: Saya baru saja memperbarui jawaban saya dengan metode inkremental untuk memperkirakan jumlah apa pun, di mana Anda dapat menetapkan p menjadi 0,25, 0,75, atau nilai apa pun dalam [0,1].
Tyler Streeter
10
Ini berfungsi dengan baik untuk maksud, tetapi saya tidak melihat bagaimana ini menghasilkan sesuatu yang mendekati median. Ambil urutan stempel waktu milidetik misalnya: [1328083200000, 981014400000, -628444800000, 318240000000, 949392000000]yang memiliki median 318240000000. Persamaan ini menggeser median sebelumnya sebesar +/- etadi mana nilai yang direkomendasikan adalah 0.001. Itu tidak akan berpengaruh pada angka-angka besar seperti ini, dan mungkin terlalu besar untuk angka-angka yang sangat kecil. Bagaimana Anda memilih etayang benar-benar memberi Anda jawaban yang benar tanpa mengetahui jawaban apriori?
mckamey
9
Bayangkan bilangan tersebut memiliki satuan, misalnya milimeter. Maka jelas eta (untuk perkiraan median) harus memiliki satuan yang sama dengan pengukuran, sehingga nilai umum seperti 0,001 sama sekali tidak masuk akal. Pendekatan yang tampaknya lebih baik adalah menyetel eta dari perkiraan berjalan dari deviasi absolut: untuk setiap nilai baru sample, perbarui cumadev += abs(sample-median). Kemudian tentukan eta = 1.5*cumadev/(k*k), dimana kjumlah sampel yang dilihat sejauh ini.
tholy
7

Ryan, saya khawatir Anda tidak melakukan mean dan varians dengan benar ... Ini muncul beberapa minggu yang lalu di sini . Dan salah satu poin kuat dari versi online (yang sebenarnya menggunakan nama metode Welford) adalah fakta bahwa ini sangat akurat dan stabil, lihat pembahasannya di sini . Salah satu kelebihannya adalah kenyataan bahwa Anda tidak perlu menyimpan jumlah total atau jumlah total kotak ...

Saya tidak dapat memikirkan pendekatan online apa pun untuk mode dan median, yang tampaknya memerlukan pertimbangan keseluruhan daftar sekaligus. Tetapi sangat mungkin bahwa pendekatan yang mirip daripada yang digunakan untuk varian dan mean akan bekerja juga untuk kemiringan dan kurtosis ...

Jaime
sumber
re: skewness and kurtosisYa. Lihat artikel ini: johndcook.com/blog/skewness_kurtosis
Jesse Chisholm
3

Artikel Wikipedia yang dikutip dalam pertanyaan berisi rumus-rumus untuk menghitung kemiringan dan kurtosis secara online.

Untuk mode - saya yakin - tidak ada cara melakukan ini secara online. Mengapa? Asumsikan bahwa semua nilai masukan Anda berbeda selain yang terakhir yang menduplikasi yang sebelumnya. Dalam hal ini Anda harus mengingat semua nilai yang sudah terlihat di input untuk mendeteksi bahwa nilai terakhir menduplikasi nilai yang terlihat sebelumnya dan menjadikannya yang paling sering.

Untuk median hampir sama - sampai input terakhir anda tidak tahu nilai apa yang akan menjadi median jika semua nilai input berbeda karena bisa saja sebelum atau sesudah median saat ini. Jika Anda mengetahui panjang input, Anda dapat menemukan median tanpa menyimpan semua nilai dalam memori, tetapi Anda masih harus menyimpan banyak dari nilai tersebut (saya kira sekitar setengahnya) karena urutan input yang buruk dapat menggeser median dengan berat di paruh kedua mungkin menghasilkan nilai apa pun dari paruh pertama median.

(Perhatikan bahwa saya mengacu pada perhitungan yang tepat saja.)

Daniel Brückner
sumber
2

Jika Anda memiliki miliaran poin data, kemungkinan Anda membutuhkan jawaban yang tepat, bukan jawaban yang mendekati. Umumnya, jika Anda memiliki miliaran titik data, proses yang mendasari yang menghasilkannya kemungkinan besar akan mematuhi semacam properti stasioneritas / ergodisitas / pencampuran statistik. Selain itu, mungkin penting apakah Anda mengharapkan distribusi berkelanjutan atau tidak.

Dalam keadaan ini, terdapat algoritme untuk on-line, memori rendah, estimasi jumlah (median adalah kasus khusus dari 0,5 kuantil), serta mode, jika Anda tidak memerlukan jawaban yang tepat. Ini adalah bidang statistik yang aktif.

contoh estimasi kuantil: http://www.computer.org/portal/web/csdl/doi/10.1109/WSC.2006.323014

Contoh estimasi mode: Bickel DR. Estimator yang kuat dari mode dan kemiringan data kontinu. Statistik Komputasi dan Analisis Data. 2002; 39: 153–163. doi: 10.1016 / S0167-9473 (01) 00057-3.

Ini adalah bidang aktif statistik komputasi. Anda memasuki bidang di mana tidak ada satu pun algoritme tepat terbaik, tetapi keragamannya (penaksir statistik, sebenarnya), yang memiliki properti, asumsi, dan kinerja yang berbeda. Ini matematika eksperimental. Mungkin ada ratusan hingga ribuan makalah tentang masalah ini.

Pertanyaan terakhir adalah apakah Anda benar-benar membutuhkan skewness dan kurtosis sendiri, atau lebih mungkin beberapa parameter lain yang mungkin lebih dapat diandalkan dalam mengkarakterisasi distribusi probabilitas (dengan asumsi Anda memiliki distribusi probabilitas!). Apakah Anda mengharapkan seorang Gaussian?

Apakah Anda memiliki cara untuk membersihkan / memproses data agar sebagian besar menjadi Gaussian? (misalnya, jumlah transaksi keuangan seringkali agak Gaussian setelah menggunakan logaritma). Apakah Anda mengharapkan deviasi standar yang terbatas? Apakah Anda mengharapkan ekor gemuk? Apakah jumlah yang Anda pedulikan dalam jumlah besar atau ekor?

Matt Kennel
sumber
2

Semua orang terus mengatakan bahwa Anda tidak dapat melakukan mode secara online tetapi itu tidak benar. Berikut adalah artikel yang menjelaskan algoritme untuk melakukan masalah ini yang ditemukan pada tahun 1982 oleh Michael E. Fischer dan Steven L. Salzberg dari Universitas Yale. Dari artikel:

Algoritme temuan mayoritas menggunakan salah satu registernya untuk penyimpanan sementara satu item dari aliran; item ini adalah kandidat saat ini untuk elemen mayoritas. Register kedua adalah penghitung yang diinisialisasi ke 0. Untuk setiap elemen aliran, kami meminta algoritme untuk melakukan rutinitas berikut. Jika penghitung membaca 0, instal elemen aliran saat ini sebagai kandidat mayoritas baru (menggantikan elemen lain yang mungkin sudah ada di register). Kemudian, jika elemen saat ini cocok dengan kandidat mayoritas, tambahkan penghitung; jika tidak, kurangi penghitung. Pada titik siklus ini, jika bagian dari aliran yang dilihat sejauh ini memiliki elemen mayoritas, elemen tersebut ada di register kandidat, dan penghitung memiliki nilai yang lebih besar dari 0. Bagaimana jika tidak ada unsur mayoritas? Tanpa melewatkan kedua data tersebut — yang tidak mungkin dilakukan dalam lingkungan streaming — algoritme tidak selalu dapat memberikan jawaban yang tidak ambigu dalam situasi ini. Ini hanya menjanjikan untuk mengidentifikasi elemen mayoritas dengan benar jika ada.

Itu juga dapat diperpanjang untuk menemukan N teratas dengan lebih banyak memori tetapi ini harus menyelesaikannya untuk mode.

hackartist
sumber
4
Itu adalah algoritme yang menarik, tetapi kecuali saya melewatkan sesuatu, sementara semua nilai mayoritas akan menjadi mode, tidak semua mode akan menjadi nilai mayoritas.
jkebinger
Tautan telah mati, jadi saya senang deskripsinya disertakan. TAPI, seperti yang dijelaskan, penghitung hanya bertambah jika kandidat mayoritas kejadian kedua berdekatan dengan kejadian pertama. Data yang diurutkan secara IMPLIES. Yang TIDAK dijamin dalam kasus data online (streaming). Dengan data yang diurutkan secara acak, ini tidak mungkin untuk menemukan mode apa pun.
Jesse Chisholm
1

Pada akhirnya jika Anda tidak memiliki pengetahuan parametrik a priori tentang distribusi, saya pikir Anda harus menyimpan semua nilai.

Yang mengatakan kecuali Anda berurusan dengan semacam situasi patologis, remedian (Rousseuw dan Bassett 1990) mungkin cukup baik untuk tujuan Anda.

Secara sederhana, ini melibatkan penghitungan median kumpulan median.


sumber
0

median dan mode tidak dapat dihitung secara online hanya dengan menggunakan ruang konstan yang tersedia. Namun, karena median dan mode lebih "deskriptif" daripada "kuantitatif", Anda dapat memperkirakannya misalnya dengan mengambil sampel kumpulan data.

Jika data terdistribusi normal dalam jangka panjang, Anda dapat menggunakan mean Anda untuk memperkirakan median.

Anda juga dapat memperkirakan median menggunakan teknik berikut: buat estimasi median M [i] untuk setiap, katakanlah, 1.000.000 entri dalam aliran data sehingga M [0] adalah median dari satu juta entri pertama, M [1] the median dari satu juta entri kedua dll. Kemudian gunakan median dari M [0] ... M [k] sebagai penduga median. Ini tentu saja menghemat ruang, dan Anda dapat mengontrol seberapa banyak Anda ingin menggunakan ruang dengan "menyetel" parameter 1.000.000. Ini juga dapat digeneralisasikan secara rekursif.

Antti Huima
sumber
0

Oke bung coba ini:

untuk c ++:

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;
}

di mana Anda mengatakan Anda sudah dapat menghitung varians sampel (svar) dan rata-rata (avg) Anda mengarahkannya ke fungsi Anda untuk melakukannya.

Juga, lihat hal perkiraan Pearson. pada kumpulan data yang besar itu akan sangat mirip. 3 (mean - median) / deviasi standar Anda memiliki median sebagai maks - min / 2

karena mode floats tidak ada artinya. seseorang biasanya akan memasukkannya ke dalam wadah dengan ukuran yang signifikan (seperti 1/100 * (maks - min)).

peter
sumber
-1

Saya cenderung menggunakan ember, yang bisa adaptif. Ukuran ember harus sesuai dengan yang Anda butuhkan. Kemudian saat setiap titik data masuk, Anda menambahkan satu ke jumlah keranjang yang relevan. Ini akan memberi Anda perkiraan sederhana untuk median dan kurtosis, dengan menghitung setiap keranjang sebagai nilainya yang ditimbang oleh jumlahnya.

Satu masalah bisa jadi adalah hilangnya resolusi pada floating point setelah miliaran operasi, yaitu menambahkan satu tidak akan mengubah nilainya lagi! Untuk mengatasi ini, jika ukuran ember maksimum melebihi beberapa batas, Anda dapat mengambil banyak dari semua hitungan.

dan
sumber
-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)
antoineber
sumber
Bisa menggunakan beberapa penjelasan untuk menghubungkan ini dengan pertanyaan asli dengan lebih baik.
Erica