Saya curiga ini adalah pertanyaan yang tidak biasa dan bersifat eksploratif, jadi tolong ajukan pertanyaan ini kepada saya.
Saya bertanya-tanya apakah seseorang dapat menerapkan gagasan pentingnya pengambilan sampel untuk pengambilan sampel Gibbs. Inilah yang saya maksud: dalam pengambilan sampel Gibbs, kami mengubah nilai satu variabel (atau blok variabel) pada suatu waktu, pengambilan sampel dari probabilitas bersyarat mengingat variabel yang tersisa.
Namun, mungkin tidak mungkin atau tidak mudah untuk mengambil sampel dari probabilitas kondisional yang tepat. Jadi alih-alih, kami mengambil sampel dari distribusi proposal dan menggunakan, misalnya, Metropolis-Hastings (MH).
Sejauh ini bagus. Tapi di sini ada jalan yang berbeda: apa yang terjadi jika kita, alih-alih menggunakan MH, menggunakan gagasan yang sama dengan yang digunakan dalam sampel kepentingan, yaitu kita mengambil sampel dari dan mempertahankan bobot penting dari sampel saat ini?
Secara lebih rinci: anggap kita memiliki variabel dan distribusi dengan faktor sehingga . Kami menjaga probabilitas proposal digunakan untuk sampel nilai saat ini dari setiap variabel . Pada setiap langkah kami mengubah subset dari variabel dan memperbarui (hanya faktor dan yang terpengaruh). Kami mengambil sampel dan bobot pentingnya untuk menghitung statistik apa pun yang kami minati.
Apakah algoritma ini benar? Jika tidak, ada alasan jelas mengapa tidak? Secara intuitif masuk akal bagi saya karena tampaknya melakukan hal yang sama dengan kepentingan sampel, tetapi dengan sampel yang tergantung.
Saya menerapkan ini untuk model jalan acak Gaussian dan mengamati bahwa bobot menjadi lebih kecil dan lebih kecil (tetapi tidak monoton), sehingga sampel awal pada akhirnya memiliki terlalu banyak kepentingan dan mendominasi statistik. Saya cukup yakin implementasinya tidak bermasalah, karena pada setiap langkah saya membandingkan bobot yang diperbarui dengan perhitungan brute force secara eksplisit. Perhatikan bahwa bobot tidak turun tanpa batas ke nol, karena mereka mana dan adalah produk dengan jumlah kepadatan terbatas, dan setiap sampel diperoleh dari distribusi Normal yang jarang jarang menjadi nol.
Jadi saya mencoba memahami mengapa bobot turun seperti itu, dan apakah ini merupakan konsekuensi dari metode ini sebenarnya tidak benar.
Berikut definisi algoritma yang lebih tepat, yang diterapkan pada jalan acak Gaussian pada variabel . Kode berikut di bawah ini.
Modelnya hanyalah , dengan tetap pada .
Berat sampel saat ini adalah , di mana adalah kepadatan Gaussian dan adalah distribusi dari mana nilai saat ini telah dijadikan sampel. Awalnya, kami hanya sampel nilai-nilai secara maju, jadi dan bobot awal adalah .
Kemudian pada setiap langkah saya memilih untuk diubah. Saya mencicipi nilai baru untuk dari , jadi kepadatan ini menjadi distribusi proposal yang digunakan baru untuk .
Untuk memperbarui bobot, saya membaginya dengan kepadatan dan dari nilai lama menurut dan , dan kalikan dengan densitas dan dari nilai baru menurut dan . Ini memperbarui numerator dari bobot.
Untuk memperbarui penyebut , saya gandakan bobotnya dengan proposal lama (dengan demikian menghapusnya dari penyebut) dan membaginya dengan .
(Karena saya mencicipi dari normal yang berpusat pada , selalu sama dengan sehingga mereka membatalkan dan implementasinya tidak tidak benar-benar menggunakannya).
Seperti yang saya sebutkan sebelumnya, dalam kode saya membandingkan perhitungan bobot tambahan ini dengan perhitungan eksplisit yang sebenarnya hanya untuk memastikan.
Ini kode untuk referensi.
println("Original sample: " + currentSample);
int flippedVariablesIndex = 1 + getRandom().nextInt(getVariables().size() - 1);
println("Flipping: " + flippedVariablesIndex);
double oldValue = getValue(currentSample, flippedVariablesIndex);
NormalDistribution normalFromBack = getNormalDistribution(getValue(currentSample, flippedVariablesIndex - 1));
double previousP = normalFromBack.density(oldValue);
double newValue = normalFromBack.sample();
currentSample.set(getVariable(flippedVariablesIndex), newValue);
double previousQ = fromVariableToQ.get(getVariable(flippedVariablesIndex));
fromVariableToQ.put(getVariable(flippedVariablesIndex), normalFromBack.density(newValue));
if (flippedVariablesIndex < length - 1) {
NormalDistribution normal = getNormalDistribution(getValue(currentSample, flippedVariablesIndex + 1));
double oldForwardPotential = normal.density(oldValue);
double newForwardPotential = normal.density(newValue);
// println("Removing old forward potential " + oldForwardPotential);
currentSample.removePotential(new DoublePotential(oldForwardPotential));
// println("Multiplying new forward potential " + newForwardPotential);
currentSample.updatePotential(new DoublePotential(newForwardPotential));
}
// println("Removing old backward potential " + previousP);
currentSample.removePotential(new DoublePotential(previousP));
// println("Multiplying (removing from divisor) old q " + previousQ);
currentSample.updatePotential(new DoublePotential(previousQ));
println("Final sample: " + currentSample);
println();
// check by comparison to brute force calculation of weight:
double productOfPs = 1.0;
for (int i = 1; i != length; i++) {
productOfPs *= getNormalDistribution(getValue(currentSample, i - 1)).density(getValue(currentSample, i));
}
double productOfQs = Util.fold(fromVariableToQ.values(), (p1, p2) -> p1*p2, 1.0);
double weight = productOfPs/productOfQs;
if (Math.abs(weight - currentSample.getPotential().doubleValue()) > 0.0000001) {
println("Error in weight calculation");
System.exit(0);
}