Saya memiliki beberapa pengamatan, dan saya ingin meniru sampel berdasarkan pengamatan ini. Di sini saya mempertimbangkan model non-parametrik, khususnya, saya menggunakan kernel smoothing untuk memperkirakan CDF dari pengamatan terbatas. Kemudian saya menggambar nilai secara acak dari CDF yang diperoleh. Berikut ini adalah kode saya, (idenya adalah mendapatkan kumulatif secara acak probabilitas menggunakan distribusi seragam, dan ambil kebalikan dari CDF sehubungan dengan nilai probabilitas)
x = [randn(100, 1); rand(100, 1)+4; rand(100, 1)+8];
[f, xi] = ksdensity(x, 'Function', 'cdf', 'NUmPoints', 300);
cdf = [xi', f'];
nbsamp = 100;
rndval = zeros(nbsamp, 1);
for i = 1:nbsamp
p = rand;
[~, idx] = sort(abs(cdf(:, 2) - p));
rndval(i, 1) = cdf(idx(1), 1);
end
figure(1);
hist(x, 40)
figure(2);
hist(rndval, 40)
Seperti yang ditunjukkan dalam kode, saya menggunakan contoh sintetis untuk menguji prosedur saya, tetapi hasilnya tidak memuaskan, seperti yang diilustrasikan oleh dua gambar di bawah ini (yang pertama adalah untuk pengamatan simulasi, dan gambar kedua menunjukkan histogram yang diambil dari perkiraan CDF) :
Adakah yang tahu di mana masalahnya? Terima kasih sebelumnya.
sumber
Jawaban:
Kira-kira penduga kepadatan kernel (KDE) menghasilkan distribusi yang merupakan campuran lokasi dari distribusi kernel, sehingga untuk menggambar nilai dari estimasi kepadatan kernel yang Anda butuhkan adalah (1) mengambil nilai dari kepadatan kernel dan kemudian (2) pilih salah satu titik data secara acak dan tambahkan nilainya ke hasil (1) secara independen.
Berikut adalah hasil dari prosedur ini yang diterapkan pada dataset seperti yang ada di pertanyaan.
Histogram di sebelah kiri menggambarkan sampel. Untuk referensi, kurva hitam memplot kepadatan dari mana sampel diambil. Kurva merah memplot KDE sampel (menggunakan bandwidth sempit). (Ini bukan masalah, atau bahkan tidak terduga, bahwa puncak merah lebih pendek dari puncak hitam: KDE menyebarkan berbagai hal, sehingga puncak akan menjadi lebih rendah untuk mengimbangi.)
Histogram di sebelah kanan menggambarkan sampel (dengan ukuran yang sama) dari KDE. Kurva hitam dan merah sama dengan sebelumnya.
Terbukti, prosedur yang digunakan untuk sampel dari kepadatan bekerja. Ini juga sangat cepat:
R
implementasi di bawah ini menghasilkan jutaan nilai per detik dari setiap KDE. Saya telah banyak berkomentar untuk membantu dalam porting ke Python atau bahasa lain. Algoritma sampling itu sendiri diimplementasikan dalam fungsirdens
dengan garisrkernel
mengambiln
sampel iid dari fungsi kernel sementarasample
mengambiln
sampel dengan penggantian dari datax
. Operator "+" menambahkan dua larik komponen sampel dengan komponen.Bagi mereka yang menginginkan demonstrasi formal tentang kebenaran, saya menawarkannya di sini. Biarkan mewakili distribusi kernel dengan CDF dan biarkan datanya . Dengan definisi estimasi kernel, CDF dari KDE adalahK FK x =( x1, x2, ... , xn)
Resep sebelumnya mengatakan untuk menggambar dari distribusi empiris data (yaitu, ia mencapai nilai dengan probabilitas untuk setiap ), menggambar secara mandiri variabel acak dari distribusi kernel, dan menjumlahkannya. Saya berutang bukti bahwa fungsi distribusi adalah fungsi KDE. Mari kita mulai dengan definisi dan melihat ke mana ia mengarah. Biarkan menjadi bilangan real. Pengkondisian pada memberiX xsaya 1 / n saya Y X+ Y x X
seperti yang diklaim.
sumber
Anda mengambil sampel dari CDF terlebih dahulu dengan membalikkannya. CDF terbalik disebut fungsi kuantil; ini adalah pemetaan dari [0,1] ke domain RV. Anda kemudian sampel RV seragam acak sebagai persentil dan meneruskannya ke fungsi kuantil untuk mendapatkan sampel acak dari distribusi itu.
sumber
Di sini, saya juga ingin memposting kode Matlab mengikuti ide yang dijelaskan oleh whuber, untuk membantu mereka yang lebih akrab dengan Matlab daripada R.
Berikut ini hasilnya:
Tolong beritahu saya jika ada yang menemukan masalah dengan pemahaman dan kode saya. Terima kasih.
sumber
Tanpa melihat terlalu dekat dengan implementasi Anda, saya tidak sepenuhnya mendapatkan prosedur pengindeksan Anda untuk menarik dari ICDF. Saya pikir Anda menarik dari CDF, bukan kebalikannya. Inilah implementasi saya:
sumber