Bagaimana cara mengambil sampel dari distribusi normal dengan mean dan varian yang dikenal menggunakan bahasa pemrograman konvensional?

36

Saya tidak pernah mengikuti kursus statistik, jadi saya harap saya bertanya di tempat yang tepat di sini.

Misalkan saya hanya memiliki dua data yang menggambarkan distribusi normal: mean dan varians σ 2 . Saya ingin menggunakan komputer untuk secara acak mengambil sampel dari distribusi ini sehingga saya menghormati dua statistik ini.μσ2

Sudah cukup jelas bahwa saya dapat menangani mean dengan hanya menormalkan sekitar 0: cukup tambahkan untuk setiap sampel sebelum mengeluarkan sampel. Tapi saya tidak melihat bagaimana pemrograman menghasilkan sampel untuk menghormati σ 2 .μσ2

Program saya akan menggunakan bahasa pemrograman konvensional; Saya tidak memiliki akses ke paket statistik apa pun.

Fixee
sumber
Apakah bahasa Anda memiliki generator nomor acak? Apakah generator ini dari distribusi yang seragam saja atau dapat menghasilkan dari distribusi normal juga?
ttnphns
@ttnphns: Hampir setiap bahasa komputer dilengkapi dengan penghasil angka acak. Mereka adalah generator yang sangat seragam pada beberapa domain yang terbatas.
Fixee

Jawaban:

33

Jika Anda dapat sampel dari distribusi tertentu dengan rata-rata 0 dan varians 1, maka Anda dapat dengan mudah sampel dari transformasi skala-lokasi distribusi tersebut, yang memiliki mean dan varians σ 2 . Jika x adalah sampel dari rata-rata 0 dan varian 1 distribusi maka σ x + μ adalah sampel dengan rata-rata μ dan varians σ 2 . Jadi, yang harus Anda lakukan adalah menskalakan variabel dengan standar deviasi σ (akar kuadrat dari varians) sebelum menambahkan mean μ .μσ2x

σx+μ
μσ2σμ

Bagaimana Anda benar-benar mendapatkan simulasi dari distribusi normal dengan mean 0 dan varian 1 adalah cerita yang berbeda. Sangat menyenangkan dan menarik untuk mengetahui bagaimana menerapkan hal-hal seperti itu, tetapi apakah Anda menggunakan paket statistik atau bahasa pemrograman atau tidak, saya akan merekomendasikan agar Anda memperoleh dan menggunakan fungsi atau perpustakaan yang sesuai untuk pembuatan angka acak. Jika Anda ingin saran tentang perpustakaan apa yang akan digunakan, Anda mungkin ingin menambahkan informasi spesifik tentang bahasa pemrograman yang Anda gunakan.

Sunting: Dalam terang komentar, beberapa jawaban lain dan fakta bahwa Fixee menerima jawaban ini, saya akan memberikan beberapa rincian lebih lanjut tentang bagaimana seseorang dapat menggunakan transformasi variabel seragam untuk menghasilkan variabel normal.

  • Salah satu metode, sudah disebutkan dalam komentar oleh VitalStatistix , adalah metode Box-Muller yang mengambil dua variabel acak seragam independen dan menghasilkan dua variabel acak normal independen. Metode serupa yang menghindari perhitungan dua fungsi transendental sin dan cos dengan mengorbankan beberapa simulasi telah diposting sebagai jawaban oleh francogrex .
  • Metode yang sepenuhnya umum adalah transformasi dari variabel acak seragam oleh fungsi distribusi terbalik. Jika terdistribusi secara seragam pada [ 0 , 1 ] maka Φ - 1 ( U ) memiliki distribusi normal standar. Meskipun tidak ada rumus analitik eksplisit untuk Φ - 1 , itu dapat dihitung dengan perkiraan numerik yang akurat. Implementasi saat ini di R (terakhir saya periksa) menggunakan ide ini. Metode ini secara konsep sangat sederhana, tetapi membutuhkan implementasi yang akuratU[0,1]
    Φ1(U)
    Φ1 , yang mungkin tidak meluas seperti fungsi transendental (lainnya)Φ1log , dosa dan cos .
  • Beberapa jawaban menyebutkan kemungkinan menggunakan teorema limit pusat untuk mendekati distribusi normal sebagai rata-rata variabel acak seragam. Ini umumnya tidak dianjurkan. Argumen yang disajikan, seperti mencocokkan rata-rata 0 dan varians 1, dan pertimbangan dukungan distribusi tidak meyakinkan. Dalam Latihan 2.3 dalam "Memperkenalkan Metode Monte Carlo dengan R" oleh Christian P. Robert dan George Casella generator ini disebut kuno dan perkiraannya disebut sangat buruk .
  • Ada sejumlah ide lain yang membingungkan. Bab 3 dan, khususnya, Bagian 3.4, dalam "Seni Pemrograman Komputer" Vol. 2 oleh Donald E. Knuth adalah referensi klasik tentang pembuatan angka acak. Brian Ripley menulis Computer Generation of Random Variables: A Tutorial , yang mungkin berguna. Buku yang disebutkan oleh Robert dan Casella, atau mungkin Bab 2 dalam buku mereka yang lain, "metode statistik Monte Carlo", juga direkomendasikan.

Pada akhirnya, metode yang diimplementasikan dengan benar tidak lebih baik daripada generator nomor acak semu yang digunakan. Secara pribadi, saya lebih suka mengandalkan perpustakaan tujuan khusus yang saya percaya dapat dipercaya. Saya hampir selalu mengandalkan metode yang diterapkan dalam R baik secara langsung di R atau melalui API di C / C ++. Jelas, ini bukan solusi untuk semua orang, tetapi saya tidak cukup akrab dengan perpustakaan lain untuk merekomendasikan alternatif.

NRH
sumber
(+1) Jawaban dan saran yang bagus untuk OP.
kardinal
18
Saya tidak yakin apakah saya membuat komentar yang tidak perlu di sini, tetapi, jika Anda hanya memiliki akses ke generator nomor acak yang seragam, maka Anda dapat menggunakan Box-Muller Transform untuk menghasilkan angka acak N (0,1) yang independen. Singkatnya, jika U_1 dan U_2 adalah undian independen dari distribusi Uniform (0,1) makadan
2log(U1)cos(2πU2)
2log(U1)sin(2πU2)
2
@Vital: Bukan komentar yang tidak perlu; salah satu yang baik. Transformasi Box-Muller mungkin adalah yang paling mudah untuk diprogram dengan peluang minimal untuk melakukan sesuatu yang buruk secara tidak sengaja. Ini bukan yang tercepat , tetapi cukup kompetitif. Yang mengatakan, menggunakan pustaka kode yang mapan mungkin masih lebih aman, terutama karena tempat di mana seseorang kemungkinan besar akan membuat kesalahan langkah adalah bagaimana input varian acak seragam dihasilkan!
kardinal
@Vital: Terima kasih, ini yang saya cari. Jika Anda ingin mengubah komentar Anda menjadi jawaban, saya akan dengan senang hati meningkatkannya.
Fixee
1
@VitalStatistix, ini komentar yang bagus, dan sepertinya inilah yang dicari OP. Mengapa tidak mengubahnya menjadi jawaban dan mungkin menguraikannya sedikit pada gagasan umum menggunakan transformasi variabel acak seragam. Saya ragu melakukan ini karena alasan yang disebutkan Kardinal terutama karena saya tidak tahu apakah generator seragam default dari bahasa apa pun adalah generator yang baik.
NRH
10

Ini benar-benar komentar tentang jawaban Michael Lew dan komentar Fixee, tetapi diposting sebagai jawaban karena saya tidak memiliki reputasi di situs ini untuk berkomentar.

[0,1]61

E[i=112Xi]=i=112E[Xi]=12×12=6
var[i=112Xi]=i=112var[Xi]=12×112=1.
CLT kemudian dapat digunakan untuk menyatakan bahwa distribusi saya=112Xsaya-6 kira-kira distribusi normal standar. Dibandingkan dengan sepuluh variabel yang dipertimbangkan oleh Michael Lew dan Fixee, diperlukan dua panggilan tambahan ke generator nomor acak, tetapi kami menghindari pembagian dengan10/12untuk mendapatkan varian unit yang diinginkan. Perlu juga diingatsaya=112Xsaya-6 dapat mengambil nilai hanya dalam kisaran [-6,6]dan dengan demikian nilai ekstrim (probabilitas sangat rendah) berbeda dari rata-rata lebih dari6standar deviasi tidak akan pernah terjadi. Ini sering merupakan masalah dalam simulasi sistem komputer dan komunikasi di mana peristiwa probabilitas sangat rendah sangat menarik.
Dilip Sarwate
sumber
5

Selain jawaban oleh NRH, jika Anda masih tidak memiliki cara untuk menghasilkan sampel acak dari "distribusi normal standar" N (0,1), di bawah ini adalah cara yang baik dan sederhana (karena Anda menyebutkan Anda tidak memiliki statistik paket, fungsi-fungsi di bawah ini harus tersedia dalam sebagian besar bahasa pemrograman standar).

1. Hasilkan u dan v sebagai dua angka acak yang terdistribusi secara merata dalam kisaran dari -1 hingga 1 oleh
u = 2 r1 - 1danv = 2 r2 - 1

2. hitung w = u^2 + v^2jika w> 1 kembali ke 1

3. mengembalikan u * z dan y = v * z dengan z= sqrt(-2ln(w)/w) kode sampel akan terlihat seperti ini:

u = 2 * random() - 1;
v = 2 * random() - 1;
w = pow(u, 2) + pow(v, 2);
if (w < 1) {
    z = sqrt((-2 * log(w)) / w);
    x = u * z;
    y = v * z;
    }

kemudian gunakan apa yang disarankan MHR di atas untuk mendapatkan penyimpangan acak N(mu, sigma^2).

francogrex
sumber
Ketika saya memposting jawaban saya di atas, saya tidak melihat bahwa @vitalStatistix memberi Anda algoritma Box-Muller Transform. Yang saya berikan di atas juga sama baiknya saya kira.
francogrex
2
Bisakah Anda jelaskan alasan untuk menghasilkan varian normal dari distribusi seragam (selain dari perspektif algoritmik) dan tidak hanya menggunakan pdf dari distribusi Gaussian / Normal secara langsung? Atau itu benar-benar salah?
Arun
4
@Arun Satu alasan: Metode kutub Marsaglia berguna ketika Anda hanya memiliki RNG yang menghasilkan penyimpangan seragam.
chl
1
@Arun itu adalah cara termudah. Anda juga dapat menghasilkan dari pdf secara langsung menggunakan misalnya metode "penolakan penerimaan". Saya memposting untuk Anda contoh sederhana di situs saya (karena tidak cukup ruang di kotak komentar di sini).
francogrex
4

Distribusi normal muncul ketika seseorang menambahkan bersama-sama banyak nilai acak dari distribusi yang sama (mirip satu sama lain, maksud saya). Jika Anda menambahkan bersama-sama sepuluh atau lebih nilai acak yang terdistribusi secara merata, maka jumlahnya hampir terdistribusi secara normal. (Tambahkan lebih dari sepuluh jika Anda menginginkannya menjadi lebih normal, tetapi sepuluh sudah cukup untuk hampir semua tujuan.)

Katakanlah bahwa nilai acak seragam Anda terdistribusi secara seragam antara 0 dan 1. Jumlahnya kemudian akan antara 0 dan 10. Kurangi 5 dari jumlah dan rata-rata dari distribusi yang dihasilkan adalah 0. Sekarang Anda membagi hasilnya dengan standar deviasi dari distribusi normal (dekat) dan gandakan hasilnya dengan standar deviasi yang diinginkan. Sayangnya saya tidak yakin apa standar deviasi dari jumlah sepuluh penyimpangan acak seragam itu, tetapi jika kita beruntung seseorang akan memberi tahu kita dalam komentar!

Saya lebih suka berbicara dengan siswa tentang distribusi normal dalam istilah ini karena utilitas asumsi distribusi normal dalam banyak sistem sepenuhnya berasal dari properti bahwa jumlah banyak pengaruh acak mengarah ke distribusi normal.

Michael Lew
sumber
Anda menggunakan Batas Pusat Thm di sini (bahwa sekelompok variabel acak iid jumlah ke variabel acak normal). Saya tidak mempertimbangkan ini karena saya pikir itu akan terlalu lambat, tetapi Anda mengatakan 10 sudah cukup ?! Ini lebih baik daripada menghitung log dan sin / cos dan sqrt!
Fixee
Juga, rata-rata rv seragam pada [0,1] adalah 0,5 dengan varian 1/12. Jika Anda menjumlahkan 10 dari ini, Anda mendapatkan rata-rata 5 dan varians 10/12 = 5/6.
Fixee
1
Dari sudut pandang pedagogis, metode ini menyediakan diskusi dan demonstrasi yang bagus dan bermanfaat. Namun, saya akan sangat menyarankan siapa pun untuk tidak menggunakan pendekatan ini dalam praktik.
kardinal
1
@Fixee: Anda harus yakin dan menyeimbangkan perhitungan log, dosa, cos and the square-root against the generation of additional uniform random variates. For example, Intel CPUs have all four of these functions as built-in operations performed in hardware. The square-root is a fundamental "arithmetic" operation according to the IEEE 754 standards.
cardinal
1
@Michael: Declaring it gives the "right" distribution is a bit of a stretch, particularly since the approximating distribution has compact support and, in many applications, one does care about how efficiently the variates can be generated. :) The point is there are several much better options available. But, I still think it provides something useful pedagogically.
cardinal