パラメータを推定したい観測データがあり、PYMC3を試す良い機会だと思いました。
私のデータは一連のレコードとして構造化されています。各レコードには、固定された 1 時間の期間に関連する観測のペアが含まれています。1 つの観測値は、特定の時間内に発生したイベントの総数です。もう 1 つの観察結果は、その期間内の成功数です。たとえば、データ ポイントは、特定の 1 時間の間に合計 1000 件のイベントがあり、そのうちの 1000 件のうち 100 件が成功したことを示す場合があります。別の期間では、合計で 1000000 のイベントが発生し、そのうち 120000 が成功したとします。観測値の分散は一定ではなく、イベントの総数に依存します。私が制御およびモデル化したいのは、この効果の一部です。
これを行うための最初のステップは、基本的な成功率を推定することです。以下のコードは、scipy を使用して生成することで 2 セットの「観察された」データを提供することにより、状況を模倣することを目的としています。ただし、正しく動作しません。
私が期待しているのは次のとおりです。
- loss_lambda_factor はおよそ 0.1 です
- total_lambda (および total_lambda_mu) はおよそ 120 です。
代わりに、モデルは非常に迅速に収束しますが、予想外の答えになります。
- total_lambda と total_lambda_mu は、それぞれ 5e5 付近の鋭いピークです。
- loss_lambda_factor はほぼ 0 です。
traceplot (レピュテーションが 10 未満であるため投稿できません) はかなり面白くありません。収束が速く、入力データに対応しない数値で鋭いピークが発生します。私が取っているアプローチに根本的な問題があるかどうか、私は興味があります. 正しい/期待される結果を得るには、次のコードをどのように変更する必要がありますか?
from pymc import Model, Uniform, Normal, Poisson, Metropolis, traceplot
from pymc import sample
import scipy.stats
totalRates = scipy.stats.norm(loc=120, scale=20).rvs(size=10000)
totalCounts = scipy.stats.poisson.rvs(mu=totalRates)
successRate = 0.1*totalRates
successCounts = scipy.stats.poisson.rvs(mu=successRate)
with Model() as success_model:
total_lambda_tau= Uniform('total_lambda_tau', lower=0, upper=100000)
total_lambda_mu = Uniform('total_lambda_mu', lower=0, upper=1000000)
total_lambda = Normal('total_lambda', mu=total_lambda_mu, tau=total_lambda_tau)
total = Poisson('total', mu=total_lambda, observed=totalCounts)
loss_lambda_factor = Uniform('loss_lambda_factor', lower=0, upper=1)
success_rate = Poisson('success_rate', mu=total_lambda*loss_lambda_factor, observed=successCounts)
with success_model:
step = Metropolis()
success_samples = sample(20000, step) #, start)
plt.figure(figsize=(10, 10))
_ = traceplot(success_samples)