Saya perlu membuat angka acak mengikuti distribusi normal dalam interval . (Saya bekerja di R.)
Saya tahu fungsi ini rnorm(n,mean,sd)
akan menghasilkan angka acak mengikuti distribusi normal, tetapi bagaimana cara menetapkan batas interval di dalamnya? Apakah ada fungsi R tertentu yang tersedia untuk itu?
x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
Jawaban:
Sepertinya Anda ingin mensimulasikan dari distribusi terpotong , dan dalam contoh spesifik Anda, normal terpotong .
Ada berbagai metode untuk melakukannya, ada yang sederhana, ada juga yang relatif efisien.
Saya akan menggambarkan beberapa pendekatan pada contoh normal Anda.
Inilah satu metode yang sangat sederhana untuk menghasilkan satu per satu (dalam beberapa jenis kodesemu):
Jika sebagian besar distribusi berada dalam batas, ini cukup masuk akal tetapi bisa menjadi sangat lambat jika Anda hampir selalu menghasilkan di luar batas.
Di R, Anda dapat menghindari loop satu per satu dengan menghitung area di dalam batas dan menghasilkan nilai yang cukup sehingga Anda bisa hampir yakin bahwa setelah membuang nilai di luar batas, Anda masih memiliki nilai sebanyak yang diperlukan.
Anda dapat menggunakan accept-reject dengan beberapa fungsi mayor yang sesuai selama interval (dalam beberapa kasus seragam akan cukup baik). Jika batas-batasnya cukup sempit relatif terhadap sd tetapi Anda tidak jauh ke ekor, jurusan seragam akan bekerja dengan normal, misalnya.
Jika Anda memiliki cdf efisien dan invers cdf (seperti
pnorm
danqnorm
untuk distribusi normal dalam R), Anda dapat menggunakan metode invers-cdf yang dijelaskan dalam paragraf pertama dari bagian simulasi halaman Wikipedia pada terpotong normal . [Akibatnya ini sama dengan mengambil seragam terpotong (terpotong pada kuantil yang diperlukan, yang sebenarnya tidak memerlukan penolakan sama sekali, karena itu hanya seragam lain) dan menerapkan cdf normal terbalik untuk itu. Perhatikan bahwa ini bisa gagal jika Anda jauh ke ekor]Ada beberapa pendekatan lain; halaman Wikipedia yang sama menyebutkan mengadaptasi metode ziggurat , yang seharusnya bisa digunakan untuk berbagai distribusi.
The Link Wikipedia yang sama menyebutkan dua paket khusus (baik di CRAN) dengan fungsi untuk menghasilkan normals terpotong:
Melihat sekeliling, banyak dari ini tercakup dalam jawaban atas pertanyaan lain (tetapi tidak persis duplikat karena pertanyaan ini lebih umum daripada hanya yang terpotong normal) ... lihat diskusi tambahan di
Sebuah. Jawaban ini
b. Jawaban Xi'an di sini , yang memiliki tautan ke makalah arXivnya (bersama dengan beberapa tanggapan berharga lainnya).
sumber
Pendekatan cepat dan kotor adalah dengan menggunakan aturan 68-95-99.7 .
Dalam distribusi normal, 99,7% dari nilai berada dalam 3 standar deviasi dari rata-rata. Jadi, jika Anda menetapkan nilai tengah ke nilai minimum yang Anda inginkan dan nilai maksimum, dan menetapkan standar deviasi Anda menjadi 1/3 dari nilai rata-rata Anda, Anda mendapatkan (sebagian besar) nilai yang berada dalam interval yang diinginkan. Maka Anda bisa membersihkan sisanya.
Baru-baru ini saya menghadapi masalah yang sama, mencoba menghasilkan nilai siswa acak untuk data tes. Dalam kode di atas, saya telah menggunakan
pmax
danpmin
untuk mengganti nilai di luar batas dengan nilai min atau max di dalam batas. Ini berfungsi untuk tujuan saya, karena saya menghasilkan jumlah data yang cukup kecil, tetapi untuk jumlah yang lebih besar itu akan memberi Anda benjolan yang terlihat pada nilai minimum dan maksimum. Jadi, tergantung pada tujuan Anda, mungkin lebih baik membuang nilai-nilai itu, menggantinya denganNA
s, atau "menggulung kembali" nilai-nilai itu sampai nilai-nilai tersebut berada dalam batas.sumber
sample(x=min:max, prob=dnorm(...))
mungkin itu cara yang lebih mudah untuk melakukannya.sample(x=min:max, prob=dnorm(...))
yang tampaknya sedikit lebih pendek dari jawaban Anda.sample()
trik ini hanya berguna jika Anda mencoba untuk memilih bilangan bulat acak, atau nilai diskrit lain yang telah ditentukan sebelumnya.Tidak ada fungsi inbuilt untuk nilai yang dihasilkan dari distribusi terpotong, tetapi sepele untuk memprogram metode ini menggunakan fungsi biasa untuk menghasilkan variabel acak. Berikut adalah
R
fungsi sederhanartruncnorm
yang mengimplementasikan metode ini dalam beberapa baris kode.Ini adalah fungsi vectorised yang akan menghasilkan
N
variabel acak IID dari distribusi normal terpotong. Akan mudah untuk memprogram fungsi untuk distribusi terpotong lainnya melalui metode yang sama. Juga tidak akan terlalu sulit untuk memprogram kerapatan terkait dan fungsi kuantil untuk distribusi terpotong.sumber