我有一些我想估计参数的观测数据,我认为这将是一个尝试 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。
跟踪图(由于声誉低于 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)