首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PyMC:分层隐马尔可夫模型

PyMC:分层隐马尔可夫模型
EN

Stack Overflow用户
提问于 2013-11-29 23:45:44
回答 4查看 2.4K关注 0票数 1

这是PyMC: Parameter estimation in a Markov system的后续文章

我有一个系统,由它在每个时间步的位置和速度来定义。系统的行为定义为:

代码语言:javascript
复制
vel = vel + damping * dt
pos =  pos + vel * dt

所以,这是我的PyMC模型。估计velpos,最重要的是damping

代码语言:javascript
复制
# PRIORS
damping = pm.Normal("damping", mu=-4, tau=(1 / .5**2))
# we assume some system noise
tau_system_noise = (1 / 0.1**2)

# the state consist of (pos, vel); save in lists
# vel: we can't judge the initial velocity --> assume it's 0 with big std
vel_states = [pm.Normal("v0", mu=-4, tau=(1 / 2**2))]
# pos: the first pos is just the observation
pos_states = [pm.Normal("p0", mu=observations[0], tau=tau_system_noise)]

for i in range(1, len(observations)):
    new_vel = pm.Normal("v" + str(i),
                        mu=vel_states[-1] + damping * dt,
                        tau=tau_system_noise)
    vel_states.append(new_vel)
    pos_states.append(
        pm.Normal("s" + str(i),
                  mu=pos_states[-1] + new_vel * dt,
                  tau=tau_system_noise)
    )

# we assume some observation noise
tau_observation_noise = (1 / 0.5**2)
obs = pm.Normal("obs", mu=pos_states, tau=tau_observation_noise, value=observations, observed=True)

下面是我运行采样的方式:

代码语言:javascript
复制
mcmc = pm.MCMC([damping, obs, vel_states, pos_states])
mcmc.sample(50000, 25000)
pm.Matplot.plot(mcmc.get_node("damping"))
damping_samples = mcmc.trace("damping")[:]
print "damping -- mean:%f; std:%f" % (mean(damping_samples), std(damping_samples))
print "real damping -- %f" % true_damping

damping的值由先验决定。即使我将之前的改变为制服或其他什么,它仍然是这样的。

我做错了什么?它与前面的示例非常相似,只是有了另一个层。

这个问题的完整IPython笔记本可以在这里找到:http://nbviewer.ipython.org/github/sotte/random_stuff/blob/master/PyMC%20-%20HMM%20Dynamic%20System.ipynb

编辑:采样的一些说明和代码。

EDIT2:@Chris answer没有帮助。我不能使用AdaptiveMetropolis,因为*_states似乎不是模型的一部分。

EN

回答 4

Stack Overflow用户

发布于 2013-12-02 23:15:29

再看一遍,这个模型有几个问题。首先,也是最重要的,您没有将所有PyMC对象添加到模型中。您只添加了[damping, obs]。您应该将所有PyMC节点传递给模型。

另外,请注意,您不需要同时调用ModelMCMC。这很好:

代码语言:javascript
复制
model = pm.MCMC([damping, obs, vel_states, pos_states])

对于PyMC来说,最好的工作流程是将您的模型保存在与运行逻辑分开的文件中。这样,您就可以导入模型并将其传递给MCMC

代码语言:javascript
复制
import my_model

model = pm.MCMC(my_model)

或者,您可以将模型编写为函数,返回locals (或vars),然后调用函数作为MCMC的参数。例如:

代码语言:javascript
复制
def generate_model():

    # put your model definition here

    return locals()

model = pm.MCMC(generate_model())
票数 1
EN

Stack Overflow用户

发布于 2013-12-03 09:46:03

假设您知道模型的结构-您正在进行参数估计,而不是系统识别-您可以将PyMC模型构建为回归模型,将未知阻尼、初始位置和初始速度作为参数以及位置数组和观测值。

也就是说,PM类表示点质量系统:

代码语言:javascript
复制
pm = PM(true_damping)

positions, velocities = pm.integrate(true_pos, true_vel, N, dt)

# Assume little system noise
std_system_noise = 0.05
tau_system_noise = 1.0/std_system_noise**2

# Treat the real positions as observations
observations = positions + np.random.randn(N,)*std_system_noise

# Damping is modelled with a Uniform prior
damping = mc.Uniform("damping", lower=-4.0, upper=4.0, value=-0.5)

# Initial position & velocity unknown -> assume Uniform priors
init_pos = mc.Uniform("init_pos", lower=-1.0, upper=1.0, value=0.5)
init_vel = mc.Uniform("init_vel", lower=0.0, upper=2.0, value=1.5)

@mc.deterministic
def det_pos(d=damping, pi=init_pos, vi=init_vel):
    # Apply damping, init_pos and init_vel estimates and integrate
    pm.damping = d.item()
    pos, vel = pm.integrate(pi, vi, N, dt)
    return pos

# Standard deviation is modelled with a Uniform prior
std_pos = mc.Uniform("std", lower=0.0, upper=1.0, value=0.5)

@mc.deterministic
def det_prec_pos(s=std_pos):
    # Precision, based on standard deviation
    return 1.0/s**2

# The observations are based on the estimated positions and precision
obs_pos = mc.Normal("obs", mu=det_pos, tau=det_prec_pos, value=observations, observed=True)

# Create the model and sample
model = mc.Model([damping, init_pos, init_vel, det_prec_pos, obs_pos])
mcmc = mc.MCMC(model)
mcmc.sample(50000, 25000)

完整的清单在这里:https://gist.github.com/stuckeyr/7762371

增加N和减少dt将显著改善您的估计。

票数 1
EN

Stack Overflow用户

发布于 2013-12-01 04:52:09

你说的不合理是什么意思?它们是不是向前一个方向缩小?阻尼似乎有一个非常紧密的变化--如果你给它一个更分散的先验呢?

另外,您可以尝试在*_states数组上使用AdaptiveMetropolis采样器:

代码语言:javascript
复制
my_model.use_step_method(AdaptiveMetropolis, my_model.vel_states)

对于相关变量,它有时会混合得更好,就像这些变量可能是的那样。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20289287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档