「重要なギブス」のサンプリング方法は機能しますか?


8

これはかなり珍しい、探索的な質問だと思いますので、ご容赦ください。

ギブスサンプリングに重要性サンプリングのアイデアを適用できるかどうか疑問に思っています。意味は次のとおりです。ギブスサンプリングでは、一度に1つの変数(または変数のブロック)の値を変更し、残りの変数が与えられた条件付き確率からサンプリングします。

ただし、正確な条件付き確率からサンプリングすることは不可能または簡単ではない場合があります。そのため、代わりに提案分布からサンプリングし、たとえばMetropolis-Hastings(MH)を使用します。q

ここまでは順調ですね。しかし、これは分岐したパスです:MHを使用する代わりに、重要度サンプリングで使用されたのと同じアイデアを使用するとどうなりますか?つまり、からサンプリングし、現在のサンプルの重要度重みを保持しますか?qp/q

より詳しく:となるように、変数と因数分解分布があるとます。各変数現在の値をサンプリングするために使用される提案確率を保持します。各ステップで、変数のサブセットを変更し、を更新します影響を受けると係数のみ)。サンプルとその重要度の重みを使用して、興味のある統計を計算します。x1,,xnϕ1,,ϕmpi=1mϕiqixip(x)/q(x)pq

このアルゴリズムは正しいでしょうか?そうでない場合、なぜそうではないかという明確な理由はありますか?重要なサンプリングと同じことをしているように見えますが、代わりに依存するサンプルを使用しているので、直感的にそれは私には理にかなっています。

私はこれをガウスランダムウォークモデルに実装し、重みがどんどん小さくなる(ただし、単調ではない)ので、最初のサンプルの重要性が高くなりすぎて統計が支配的になることに気付きました。各ステップで、更新された重みを明示的なブルートフォース計算と比較するため、実装にバグがないと確信しています。重みは、であり、と両方が有限数の密度の積であるため、無制限にゼロに下がらないことに注意してください。各サンプルは、まれにしかゼロにならない正規分布から取得されます。p/qpq

だから私はなぜ重みがそのように下がるのか、そしてこれがこの方法が実際に正しくない結果であるのかどうかを理解しようとしています。


次に、より正確なアルゴリズムの定義を示します。これは、変数ガウスランダムウォークに適用されます。コードは以下のとおりです。X1,,Xn

モデルは単にで、は固定されてい。XiN(Xi1,σ2),i=1,,nX00

現在のサンプルの重みは。ここで、はガウス密度、は現在の値のサンプリング元の分布です。最初は、値を順方向にサンプリングするだけなので、で、初期の重みはです。ip(xi)iq(xi)pqq=p1

次に、各ステップで、変更するを選択します。私は新しい値サンプルするためのから、この密度はのための新たな使用提案分布となるように。j{1,,n}xjXjN(Xj1,σ2)Xj

重みを更新するには、とに従って、古い値の密度とで除算します及び多重密度のによりと新しい値のに従っておよび。これにより、重みの分子が更新されます。p(xj|xj1)p(xj+1|xj)xjxj1xj+1p(xj|xj1)p(xj+1|xj)xjxj1xj+1p

分母を更新するには、重みを古い提案乗算し(したがって、分母から削除)、それを除算します。qq(xj)q(xj)

(私はを中心とする法線からをサンプリングするため、は常に等しいので、キャンセルして実装が行います実際には使用しません)。xjxj1q(xj)p(xj|xj1)

前に述べたように、コードでは、念のため、この増分重み計算を実際の明示的な計算と比較しています。


参照用のコードを以下に示します。

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);
}

重要度のサンプリングでは、ターゲット分布からのサンプルは提供されません(この場合、完全な条件)。したがって、MCMCの収束をもたらすマルコフカーネルダイナミクスは保持されません。重みが0に行っている理由を、あなたのコードを見ずに、私は見ることができないϕi
Greenparker

ありがとう。MCMC収束の定理を詳しく調べなければならないでしょう。念のためにコードを含めましたが、それはかなり簡単です。ありがとう。
user118967

1
生のコードを含める代わりに(または追加で)、アルゴリズムの実装方法を説明できますか?ターゲット分布とは何か、完全な条件

ありがとうございました。私はそうしました、これがどこか混乱するかどうか知らせてください。
user118967

@ Xi'an:ここでは、単一変数のフリップに重要度サンプリングが適用されています。提案を受け入れるか、メトロポリスヘイスティングスのようにではなく、常に受け入れますが、フリップされる変数の確率pを提案qで割ることにより、そのフリップの重要性の尺度を維持します。
user118967

回答:


4

これは興味深いアイデアですが、いくつかの難しさがあります。

  1. 標準の重要度サンプリングとは逆に、またはMetropolisedの重要度サンプリングでさえ、提案はターゲット分布と同じ空間では機能しませんが、より小さな次元の空間で機能するため、検証は不明確です[反復間で重みを維持することを強制するため、縮退に直面します]
  2. 完全な条件に欠落している正規化定数は各反復で変化しますが、考慮されません[以下を参照]
  3. 重みに制限はありません。反復に沿って、ギブスサンプラーのマルコフ検証と衝突する可能性がある同じインデックス更新の最後の発生を追跡しない限り、最終的に非常に大きな重みを持つシミュレーションが存在します。。適度な実験を実行し及びから反復ショー量の範囲をします。jn=2T=1037.656397e-073.699364e+04

詳細については、適切な正規化定数を含む2次元のターゲットをし、提案およびギブスサンプラーの重要性を実装します。。連続するシミュレーションの正しい重要度の重み([任意の関数に対する正しい期待値、つまり不偏推定量を生成するという意味で]は、いずれかです ここで、とはの周辺です。または同等に p(,)qX(|y)qY(|x)(X,Y)

p(xt,yt1)qX(xt|yt1)mY(yt1)orp(xt1,yt)qY(yt|xt1)mX(xt1)
mX()mY()p(,)
pX(xt|yt1)qX(xt|yt1)orpY(yt|xt1)qY(yt|xt1)
どちらの場合も、これにはターゲット下のとの[扱いにくい]限界密度が必要です。XYp(,)

ここで何が起こるかを、並行して重要度を重み付けしたMetropolisアルゴリズムと比較することは価値があります。(たとえば、Schuster und Klebanov、2018を参照してください。)ターゲットが再びで、提案が場合、重要度の重み は正しい[不偏推定を生成する]ため、以前の重みを更新せず、各反復でゼロから開始します。p(,)q(,|x,y)

p(x,y)q(x,y|x,y)

(C.)ギブスの提案の元の重要性に対する修正は、ギブスの提案から、ベクトル全体の新しい値、たとえば 提案すること、重要度の重み は正しい[可能な正規化がないため現在は真に一定であり、以前のギブス反復から運ばれない定数](x,y)qX(xt|yt1)qY(yt|xt)

p(xt,yt)qX(xt|yt1)qY(yt|xt)

最後の注意:コードで考慮されているランダムウォークターゲットの場合、カスケード接続により直接シミュレーションを実行できますシミュレートし、次に 与えてシミュレートします。X1X2X1

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.