(この質問のものと同様) を使用して、3 つの法線をデータに適合させるための PyMC モデルを作成しました。
import numpy as np
import pymc as mc
import matplotlib.pyplot as plt
n = 3
ndata = 500
# simulated data
v = np.random.randint( 0, n, ndata)
data = (v==0)*(10+ 1*np.random.randn(ndata)) \
+ (v==1)*(-10 + 2*np.random.randn(ndata)) \
+ (v==2)*3*np.random.randn(ndata)
# the model
dd = mc.Dirichlet('dd', theta=(1,)*n)
category = mc.Categorical('category', p=dd, size=ndata)
precs = mc.Gamma('precs', alpha=0.1, beta=0.1, size=n)
means = mc.Normal('means', 0, 0.001, size=n)
@mc.deterministic
def mean(category=category, means=means):
return means[category]
@mc.deterministic
def prec(category=category, precs=precs):
return precs[category]
obs = mc.Normal('obs', mean, prec, value=data, observed = True)
model = mc.Model({'dd': dd,
'category': category,
'precs': precs,
'means': means,
'obs': obs})
M = mc.MAP(model)
M.fit()
# mcmc sampling
mcmc = mc.MCMC(model)
mcmc.use_step_method(mc.AdaptiveMetropolis, model.means)
mcmc.use_step_method(mc.AdaptiveMetropolis, model.precs)
mcmc.sample(100000,burn=0,thin=10)
tmeans = mcmc.trace('means').gettrace()
tsd = mcmc.trace('precs').gettrace()**-.5
plt.plot(tmeans)
#plt.errorbar(range(len(tmeans)), tmeans, yerr=tsd)
plt.show()
データをサンプリングした分布は明らかに重複していますが、3 つの明確なピークがあります (下の画像を参照)。この種のデータに 3 つの法線を当てはめるのは簡単で、MCMC 実行の 99% で (-10, 0, 10) からサンプリングした平均値が得られると期待しています。 私が期待する結果の例。これは 10 件中 2 件で発生しました。 10 件中 6 件で発生した予期しない結果の例。これは奇妙です。なぜなら、-5 ではデータにピークがないため、サンプリングが行き詰まる可能性のある深刻な極小値 ((-5,-5) から (-6,-4) への移行) を実際に求めることができないからです。フィット感を改善する必要があります)。
ほとんどの場合、(アダプティブ メトロポリス) MCMC サンプリングが停止する理由は何ですか? サンプリング手順を改善するために可能な方法は何ですか?
したがって、実行は収束しますが、実際には適切な範囲を探索しません。
更新: 異なる事前確率を使用して、5/10 で正しい収束 (約 1 番目の画像) を取得し、他の 5/10 で間違った収束 (約 2 番目の画像) を取得します。基本的に、変更された行は以下の行で、AdaptiveMetropolis ステップ メソッドが削除されています。
precs = mc.Gamma('precs', alpha=2.5, beta=1, size=n)
means = mc.Normal('means', [-5, 0, 5], 0.0001, size=n)