我正在尝试进入语言处理,从简单的 HMM 开始,但构建可能需要离散参数的模型(因此 Stan 可能无法工作)。最终,我要处理大量的语言数据,所以需要相当的效率。PyMC3 似乎可能是我唯一的选择(我愿意接受建议)。
我在尝试一个简单的“隐藏”马尔可夫模型时遇到了问题——斯坦手册中的第一个 HMM 模型,其中“潜在”状态是观察到的数据。该模型包含 N=300 个人工数据,使用 Metropolis 在 PyMC3 中运行,但这需要 11 分钟,而 Stan 需要 2.5 秒(使用 NUTS)。数百倍的时间表明 Metropolis 采样器没有足够的可扩展性。PyMC3 中的 NUTS 采样器给出了“Scaling is not positive 限定”错误,尽管提供了一个非常准确的 MAP 估计值。
我还尝试在 PyMC3 中运行 N=1000 的模型。我尝试了 fmin_powell 和 L-BFGS-B 优化器。两者都运行了两个小时,并在用完我系统上的所有可用内存(16GB RAM,16GB 交换)后崩溃——不知道为什么。Stan 不需要明确的 MAP 估计,并在大约 20 秒内完成了 N=1000 的贝叶斯分析。如果我正确阅读了 Stan 手册,它只是从随机值开始,而不是 MAP 估计值。
我不清楚我的问题是由于我提供的 PyMC3 模型中的一些新手缺陷,还是 PyMC3 中的一些问题或限制,或者这是否不是 PyMC3 应该解决的那种模型(或者最终可能是贝叶斯估计)。我试图进一步对模型进行矢量化,这可能会有所帮助,但似乎无法找出可行的方法,也没有在网上看到太多可以提供指导的东西。
我用来运行模型的所有代码,以及使用的人工数据都可以在这里找到: https ://drive.google.com/folderview?id=0B8242b1Xh6pzSWFDM2lQbDZwajg&usp=sharing
型号为:
with basic_model:
#Model constants:
K=3; V=9; T=300 #num unique hidden states, num unique emissions, num instances
alpha=np.ones(K); beta=np.ones(V)
# Priors for unknown model parameters
theta = np.empty(K, dtype=object) #theta=transmission
phi = np.empty(K, dtype=object) #phi=emission
w=np.empty(T, dtype=object); z=np.empty(T-1, dtype=object); #observed emission, state
for k in range(K):
theta[k]=Dirichlet('theta'+str(k), alpha)
phi[k]=Dirichlet('phi'+str(k), beta)
#Likelihood (sampling distribution) of observationss
for t in range(1, T):
z[t-1]=Categorical('z'+str(t),theta[state[t-1]], shape=1, observed=state[t])
for t in range(T):
w[t]=Categorical('w'+str(t),phi[state[t]], shape=1, observed=emission[t])