gpt4 book ai didi

python - pymc3 : Multiple observed values

转载 作者:太空狗 更新时间:2023-10-29 21:13:46 25 4
gpt4 key购买 nike

我有一些观测数据想估计参数,我认为这是试用 PYMC3 的好机会。

我的数据结构为一系列记录。每条记录都包含一对与固定的一小时时间段相关的观察结果。一项观察是给定时间内发生的事件总数。另一个观察结果是该时间段内的成功次数。因此,例如,一个数据点可能指定在给定的 1 小时内,总共有 1000 个事件,而这 1000 个事件中有 100 个是成功的。在另一个时间段内,可能总共有1000000个事件,其中120000个是成功的。观察的方差不是恒定的,取决于事件的总数,我想控制和建模的部分原因是这种影响。

我这样做的第一步是估计潜在的成功率。我准备了下面的代码,旨在通过使用 scipy 生成两组“观察到的”数据来模拟这种情况。但是,它无法正常工作。
我希望它找到的是:

  • 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)

最佳答案

除了任何贝叶斯 MCMC 分析的缺陷外,您的方法没有任何根本性错误:(1) 不收敛,(2) 先验,(3) 模型。

不收敛:我找到了一个如下所示的轨迹图:

traceplot with burnin included

这不是一件好事,为了更清楚地了解原因,我会更改跟踪图代码以仅显示跟踪的后半部分,traceplot(success_samples[10000:]) :

traceplot with burnin removed

先验:收敛的一个主要挑战是您在 total_lambda_tau 上的先验,这是贝叶斯建模中的一个典型陷阱。尽管使用之前的 Uniform('total_lambda_tau', lower=0, upper=100000) 可能显得信息量不大,其效果是说您非常确定 total_lambda_tau很大。例如,它小于 10 的概率是 .0001。改变之前

total_lambda_tau= Uniform('total_lambda_tau', lower=0, upper=100)
total_lambda_mu = Uniform('total_lambda_mu', lower=0, upper=1000)

生成更有希望的跟踪图:

traceplot with different priors

然而,这仍然不是我在跟踪图中寻找的内容,为了获得更令人满意的结果,我建议使用“顺序扫描 Metropolis”步骤(这是 PyMC2 对类似模型的默认设置)。您可以按如下方式指定:

step =  pm.CompoundStep([pm.Metropolis([total_lambda_mu]),
pm.Metropolis([total_lambda_tau]),
pm.Metropolis([total_lambda]),
pm.Metropolis([loss_lambda_factor]),
])

这会生成一个看起来可以接受的轨迹图:

traceplot with sequential scan metropolis

模型:正如@KaiLondenberg 回应的那样,您在 total_lambda_tau 上采用的先验方法和 total_lambda_mu不是标准方法。您描述的事件总数差异很大(一小时 1,000,下一小时 1,000,000),但您的模型假定它呈正态分布。在空间流行病学中,我看到的类似数据的方法是一个更像这样的模型:

import pymc as pm, theano.tensor as T
with Model() as success_model:
loss_lambda_rate = pm.Flat('loss_lambda_rate')
error = Poisson('error', mu=totalCounts*T.exp(loss_lambda_rate),
observed=successCounts)

我敢肯定,还有其他研究社区似乎更熟悉的其他方法。

这里是 a notebook collecting up these comments .

关于python - pymc3 : Multiple observed values,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24242660/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com