Saya punya sedikit masalah yang membuat saya panik. Saya harus menulis prosedur untuk proses akuisisi online dari rangkaian waktu multivarian. Pada setiap interval waktu (misalnya 1 detik), saya mendapatkan sampel baru, yang pada dasarnya adalah vektor titik mengambang ukuran N. Operasi yang perlu saya lakukan agak rumit:
Untuk setiap sampel baru, saya menghitung persentase untuk sampel itu (dengan menormalkan vektor sehingga elemen akan berjumlah 1).
Saya menghitung vektor persentase rata-rata dengan cara yang sama, tetapi menggunakan nilai masa lalu.
Untuk setiap nilai masa lalu, saya menghitung deviasi absolut dari vektor persentase yang terkait dengan sampel tersebut dengan vektor persentase rata-rata global yang dihitung pada langkah 2. Dengan cara ini, deviasi absolut selalu berupa angka antara 0 (ketika vektor sama dengan rata-rata). vektor) dan 2 (ketika itu benar-benar berbeda).
Dengan menggunakan rata-rata penyimpangan untuk semua sampel sebelumnya, saya menghitung deviasi absolut rata-rata, yang lagi-lagi angka antara 0 dan 2.
Saya menggunakan deviasi absolut rata-rata untuk mendeteksi apakah sampel baru kompatibel dengan sampel lain (dengan membandingkan deviasi absolutnya dengan deviasi absolut rata-rata dari seluruh rangkaian yang dihitung pada langkah 4).
Karena setiap kali sampel baru dikumpulkan perubahan rata-rata global (dan juga berarti deviasi absolut juga berubah), adakah cara untuk menghitung nilai ini tanpa memindai seluruh data yang ditetapkan beberapa kali? (satu kali untuk menghitung persentase rata-rata global, dan satu kali untuk mengumpulkan penyimpangan absolut). Ok, saya tahu sangat mudah untuk menghitung rata-rata global tanpa memindai seluruh rangkaian, karena saya hanya perlu menggunakan vektor sementara untuk menyimpan jumlah setiap dimensi, tetapi bagaimana dengan deviasi absolut rata-rata? Perhitungannya termasuk abs()
operator, jadi saya perlu mengakses semua data masa lalu!
Terima kasih atas bantuan Anda.
sumber
Saya telah menggunakan pendekatan berikut di masa lalu untuk menghitung penyimpangan absolusi dengan cukup efisien (perhatikan, ini adalah pendekatan programmer, bukan ahli statistik, jadi pasti ada trik pintar seperti shabbychef yang mungkin lebih efisien).
PERINGATAN: Ini bukan algoritma online. Itu membutuhkan
O(n)
memori. Selain itu, ia memiliki kinerja kasus terburukO(n)
, untuk kumpulan data seperti[1, -2, 4, -8, 16, -32, ...]
(yaitu sama dengan perhitungan penuh). [1]Namun, karena masih berkinerja baik dalam banyak kasus penggunaan, mungkin ada baiknya memposting di sini. Misalnya, untuk menghitung penyimpangan absolut dari 10.000 angka acak antara -100 dan 100 ketika setiap item tiba, algoritma saya membutuhkan waktu kurang dari satu detik, sedangkan perhitungan ulang penuh membutuhkan waktu lebih dari 17 detik (pada mesin saya, akan bervariasi per mesin dan sesuai dengan input data). Anda perlu mempertahankan seluruh vektor dalam memori, yang mungkin menjadi kendala untuk beberapa penggunaan. Garis besar algoritma adalah sebagai berikut:
O(n)
operasi pindah, untuk banyak kasus penggunaan ini tidak demikian.Beberapa kode contoh, dengan python, ada di bawah ini. Perhatikan bahwa itu hanya memungkinkan item ditambahkan ke daftar, tidak dihapus. Ini dapat dengan mudah ditambahkan, tetapi pada saat saya menulis ini saya tidak perlu melakukannya. Alih-alih mengimplementasikan antrian prioritas sendiri, saya telah menggunakan daftar sortir dari paket blist Daniel Stutzbach yang sangat baik , yang menggunakan B + Tree secara internal.
Pertimbangkan kode ini dilisensikan di bawah lisensi MIT . Ini belum dioptimalkan atau dipoles secara signifikan, tetapi telah bekerja untuk saya di masa lalu. Versi baru akan tersedia di sini . Beri tahu saya jika Anda memiliki pertanyaan, atau temukan bug.
[1] Jika gejalanya menetap, kunjungi dokter Anda.
sumber
O(n)
memori, dan dalam kasus terburuk membutuhkan O (n) waktu untuk setiap item yang ditambahkan. Dalam data yang terdistribusi normal (dan mungkin distribusi lain) itu bekerja cukup efisien.sumber
MAD (x) hanyalah dua perhitungan median bersamaan, yang masing-masing dapat dilakukan secara online melalui algoritma binmedian .
Anda dapat menemukan kertas terkait serta kode C dan FORTRAN online di sini .
(Ini hanya penggunaan trik pintar di atas trik pintar Shabbychef, untuk menghemat memori).
Tambahan:
Ada sejumlah metode multi-pass lama untuk menghitung kuantil. Pendekatan yang populer adalah memelihara / memperbarui reservoir pengamatan berukuran deterministik yang dipilih secara acak dari sungai dan menghitung kuantil secara rekursif (lihat ulasan ini ) pada reservoir ini. Pendekatan ini (dan terkait) digantikan oleh yang diusulkan di atas.
sumber
Berikut ini memberikan perkiraan yang tidak akurat, meskipun ketidaktepatan akan tergantung pada distribusi data input. Ini adalah algoritma online, tetapi hanya mendekati penyimpangan absolut. Ini didasarkan pada algoritma yang terkenal untuk menghitung varians online, dijelaskan oleh Welford pada 1960-an. Algoritma-nya, diterjemahkan ke dalam R, terlihat seperti:
Kerjanya sangat mirip dengan fungsi varians bawaan R:
Memodifikasi algoritma untuk menghitung penyimpangan absolut hanya melibatkan
sqrt
panggilan tambahan . Namun,sqrt
memperkenalkan ketidakakuratan yang tercermin dalam hasil:Kesalahan, dihitung seperti di atas, jauh lebih besar daripada perhitungan varians:
Namun, tergantung pada kasus penggunaan Anda, besarnya kesalahan ini mungkin dapat diterima.
sumber
n
menjadi besar,error/n
semakin kecil, semakin cepat.sqrt
ketidaktepatan. Itu karena menggunakan estimasi rata-rata berjalan. Untuk melihat kapan ini akan rusak, cobaxs <- sort(rnorm(n.testitems))
Ketika saya mencoba ini dengan kode Anda (setelah memperbaikinya untuk kembalia.dev / n
), saya mendapatkan kesalahan relatif pada urutan 9% -16%. Jadi metode ini bukan invarian permutasi, yang dapat menyebabkan malapetaka ...