Bagaimana cara mengubah distribusi seragam (seperti yang dihasilkan oleh kebanyakan generator bilangan acak, misalnya antara 0,0 dan 1,0) menjadi distribusi normal? Bagaimana jika saya menginginkan mean dan deviasi standar yang saya pilih?
106
Jawaban:
The Ziggurat algoritma ini cukup efisien untuk ini, meskipun Box-Muller transformasi lebih mudah untuk menerapkan dari awal (dan tidak gila lambat).
sumber
Ada banyak metode:
sumber
Mengubah distribusi fungsi apa pun ke fungsi lain melibatkan penggunaan kebalikan dari fungsi yang Anda inginkan.
Dengan kata lain, jika Anda membidik fungsi probabilitas tertentu p (x), Anda mendapatkan distribusi dengan mengintegrasikannya -> d (x) = integral (p (x)) dan menggunakan inversnya: Inv (d (x)) . Sekarang gunakan fungsi probabilitas acak (yang memiliki distribusi seragam) dan berikan nilai hasil melalui fungsi Inv (d (x)). Anda harus mendapatkan nilai acak yang diberikan dengan distribusi sesuai dengan fungsi yang Anda pilih.
Ini adalah pendekatan matematika umum - dengan menggunakannya Anda sekarang dapat memilih fungsi probabilitas atau distribusi yang Anda miliki selama memiliki pendekatan invers atau invers yang baik.
Semoga ini membantu dan terima kasih atas komentar kecil tentang menggunakan distribusi dan bukan probabilitas itu sendiri.
sumber
Berikut adalah implementasi javascript menggunakan bentuk kutub dari transformasi Box-Muller.
sumber
Gunakan teorema batas pusat entri wikipedia mathworld entry untuk keuntungan Anda.
Hasilkan n dari bilangan terdistribusi seragam, jumlahkan, kurangi n * 0,5 dan Anda memiliki output dari distribusi yang kira-kira normal dengan mean sama dengan 0 dan varians sama dengan
(1/12) * (1/sqrt(N))
(lihat wikipedia tentang distribusi seragam untuk yang terakhir)n = 10 memberi Anda sesuatu yang setengah layak dengan cepat. Jika Anda menginginkan sesuatu yang lebih dari setengah yang layak, gunakan solusi tylers (seperti yang dicatat dalam entri wikipedia pada distribusi normal )
sumber
Saya akan menggunakan Box-Muller. Dua hal tentang ini:
Biasanya, Anda menyimpan satu nilai ke cache dan mengembalikan yang lain. Pada panggilan berikutnya untuk sampel, Anda mengembalikan nilai yang di-cache.
Anda harus menskalakan Z-score dengan standar deviasi dan menambahkan mean untuk mendapatkan nilai penuh dalam distribusi normal.
sumber
Dimana R1, R2 adalah nomor seragam acak:
DISTRIBUSI NORMAL, dengan SD 1: sqrt (-2 * log (R1)) * cos (2 * pi * R2)
Ini tepat ... tidak perlu melakukan semua putaran lambat itu!
sumber
Tampaknya luar biasa bahwa saya dapat menambahkan sesuatu ke dalamnya setelah delapan tahun, tetapi untuk kasus Java saya ingin mengarahkan pembaca ke metode Random.nextGaussian () , yang menghasilkan distribusi Gaussian dengan mean 0.0 dan deviasi standar 1.0 untuk Anda.
Penjumlahan dan / atau perkalian sederhana akan mengubah mean dan deviasi standar sesuai kebutuhan Anda.
sumber
Standar Python perpustakaan modul random memiliki apa yang Anda inginkan:
Untuk algoritme itu sendiri, lihat fungsi di random.py di pustaka Python.
The pengguna masuk sini
sumber
Ini adalah implementasi JavaScript saya dari Algorithm P ( metode Polar untuk deviasi normal ) dari Bagian 3.4.1 dari buku Donald Knuth The Art of Computer Programming :
sumber
Aku hal yang Anda harus mencoba ini di EXCEL:
=norminv(rand();0;1)
. Ini akan menghasilkan angka acak yang seharusnya terdistribusi normal dengan mean nol dan menyatukan varians. "0" dapat diberikan dengan nilai apa pun, sehingga angka-angka tersebut akan menjadi rata-rata yang diinginkan, dan dengan mengubah "1", Anda akan mendapatkan varians yang sama dengan kuadrat input Anda.Misalnya:
=norminv(rand();50;3)
akan menghasilkan bilangan yang terdistribusi normal dengan MEAN = 50 VARIANCE = 9.sumber
T Bagaimana saya dapat mengubah distribusi seragam (seperti yang dihasilkan oleh kebanyakan generator bilangan acak, misalnya antara 0,0 dan 1,0) menjadi distribusi normal?
Untuk implementasi perangkat lunak saya tahu beberapa nama generator acak yang memberi Anda urutan acak seragam semu di [0,1] (Mersenne Twister, Linear Congruate Generator). Sebut saja U (x)
Ada bidang matematika yang disebut teori probabilitas. Hal pertama: Jika Anda ingin memodelkan rv dengan distribusi integral F maka Anda dapat mencoba mengevaluasi F ^ -1 (U (x)). Dalam teori pr. Terbukti bahwa rv tersebut memiliki distribusi integral F.
Langkah 2 dapat diterapkan untuk menghasilkan rv ~ F tanpa menggunakan metode penghitungan apa pun ketika F ^ -1 dapat diturunkan secara analitik tanpa masalah. (mis. exp.distribution)
Untuk memodelkan distribusi normal, Anda dapat menghitung y1 * cos (y2), dengan y1 ~ seragam dalam [0,2pi]. dan y2 adalah distribusi relei.
T: Bagaimana jika saya menginginkan mean dan deviasi standar yang saya pilih?
Anda dapat menghitung sigma * N (0,1) + m.
Dapat dibuktikan bahwa pergeseran dan penskalaan tersebut mengarah ke N (m, sigma)
sumber
Ini adalah implementasi Matlab menggunakan bentuk kutub dari transformasi Box-Muller :
Fungsi
randn_box_muller.m
:Dan memohon
histfit(randn_box_muller(10000000),100);
ini adalah hasilnya:Jelas ini sangat tidak efisien dibandingkan dengan randn bawaan Matlab .
sumber
Saya memiliki kode berikut yang mungkin bisa membantu:
sumber
Juga lebih mudah menggunakan fungsi rnorm () yang diimplementasikan karena lebih cepat daripada menulis generator bilangan acak untuk distribusi normal. Lihat kode berikut sebagai bukti
sumber
sumber