Python pymc3:具有多维集中因子的Dirichlet

Python pymc3:具有多维集中因子的Dirichlet,python,bayesian,pymc3,multinomial,dirichlet,Python,Bayesian,Pymc3,Multinomial,Dirichlet,我正在努力实现一个模型,其中Dirichlet变量的集中系数依赖于另一个变量 情况如下: 系统因故障部件而失效(有三个部件,每次测试/观察时只有一个部件失效) 部件的失效概率取决于温度 下面是一个(评论)简短的情况实施: import numpy as np import pymc3 as pm import theano.tensor as tt # Temperature data : 3 cold temperatures and 3 warm temperatures T_data

我正在努力实现一个模型,其中Dirichlet变量的集中系数依赖于另一个变量

情况如下:

系统因故障部件而失效(有三个部件,每次测试/观察时只有一个部件失效)

部件的失效概率取决于温度

下面是一个(评论)简短的情况实施:

import numpy as np
import pymc3 as pm
import theano.tensor as tt


# Temperature data : 3 cold temperatures and 3 warm temperatures
T_data = np.array([10, 12, 14, 80, 90, 95])

# Data of failures of 3 components : [0,0,1] means component 3 failed
F_data = np.array([[0, 0, 1], \
       [0, 0, 1], \
       [0, 0, 1], \
       [1, 0, 0], \
       [1, 0, 0], \
       [1, 0, 0]])

n_component = 3

# When temperature is cold : Component 1 fails
# When temperature is warm : Component 3 fails
# Component 2 never fails

# Number of observations :
n_obs = len(F_data)


# The number of failures can be modeled as a Multinomial F ~ M(n_obs, p) with parameters 
# -  n_test : number of tests (Fixed)
# -  p : probability of failure of each component (shape (n_obs, 3))

# The probability of failure of components follows a Dirichlet distribution p ~ Dir(alpha) with parameters:
# -  alpha : concentration (shape (n_obs, 3))
# The Dirichlet distributions ensures the probabilities sum to 1 

# The alpha parameters (and the the probability of failures) depend on the temperature alpha ~ a + b * T
# - a : bias term (shape (1,3))
# - b : describes temperature dependency of alpha (shape (1,3))
_

我在示例函数中得到以下错误:


RemoteTraceback回溯(最近一次调用)
远程回溯:
"""
回溯(最近一次呼叫最后一次):
文件“/anaconda3/lib/python3.6/site packages/pymc3/parallel_sampling.py”,第73行,运行中
self.\u start\u loop()
文件“/anaconda3/lib/python3.6/site packages/pymc3/parallel_sampling.py”,第113行,在开始循环中
点,stats=self.\u compute\u point()
文件“/anaconda3/lib/python3.6/site packages/pymc3/parallel_sampling.py”,第139行,in_compute_point
点,统计=self.\u步骤\u方法步骤(self.\u点)
文件“/anaconda3/lib/python3.6/site packages/pymc3/step_methods/arraystep.py”,第247行,步骤
apoint,stats=self.astep(数组)
astep中的文件“/anaconda3/lib/python3.6/site packages/pymc3/step_methods/hmc/base_hmc.py”,第117行
“可能指定错误。”%start.energy)
ValueError:错误的初始能量:inf。模型可能指定错误。
"""
上述异常是以下异常的直接原因:
ValueError回溯(最近一次调用上次)
ValueError:错误的初始能量:inf。模型可能指定错误。
上述异常是以下异常的直接原因:
运行时错误回溯(上次最近调用)
在()
1、型号:
2#start=pm.find#u MAP()
---->3道=pm样品(5000)
/样本中的anaconda3/lib/python3.6/site-packages/pymc3/sampling.py
438打印步骤层次结构(步骤)
439试试:
-->440跟踪=\u mp\u样本(**样本参数)
441除pickle.pickle错误外:
442_log.warning(“无法pickle模型,采样单线程。”)
/anaconda3/lib/python3.6/site-packages/pymc3/sampling.py in_mp_sample(绘制、调整、步进、链、核心、链、随机种子、开始、进度条、跟踪、模型、使用mmap、**kwargs)
988尝试:
989带取样器:
-->990对于吸入式取样器:
991轨迹=轨迹[draw.chain-chain]
992如果trace.supports_sampler_stats和draw.stats不是None:
/anaconda3/lib/python3.6/site-packages/pymc3/parallel_sampling.py in_______________(self)
303
304自激活时:
-->305 draw=ProcessAdapter.recv\u draw(自激活)
306 proc,最后一次,绘制,调整,统计,警告=绘制
307如果自我进展不是无:
/recv_draw中的anaconda3/lib/python3.6/site-packages/pymc3/parallel_sampling.py(进程,超时)
221如果消息[0]=“错误”:
222 old=msg[1]
-->223六个。从(运行时错误(“链%s失败”。%proc.Chain),旧)
224 elif msg[0]=“写入完成”:
225程序可读=正确
/raise_from(值,from_值)中的anaconda3/lib/python3.6/site-packages/six.py
运行时错误:链1失败。

有什么建议吗?

错误指定的型号。在当前参数化下,
alphas
采用非正值,而
Dirichlet
分布要求它们为正值,这使得模型的指定错误

在Dirichlet多项式回归中,使用指数链接函数在线性模型的范围和Dirichlet多项式的域之间进行调解,即

alpha = exp(beta*X)
有关这方面的详细信息,请参阅

Dirichlet多项式回归模型 如果我们实现这个模型,我们可以实现良好的模型收敛和采样

import numpy as np
import pymc3 as pm
import theano
import theano.tensor as tt
from sklearn.preprocessing import scale

T_data = np.array([10,12,14,80,90,95])

# standardize the data for better sampling
T_data_z = scale(T_data)

# transform to theano tensor, so it works with tt.outer
T_data_z = theano.shared(T_data_z)

F_data = np.array([
    [0,0,1],
    [0,0,1],
    [0,0,1],
    [1,0,0],
    [1,0,0],
    [1,0,0],
])

# N = num_obs, K = num_components
N, K = F_data.shape

with pm.Model() as dmr_model:
    a = pm.Normal('a', mu=0, sd=1, shape=K)
    b = pm.Normal('b', mu=0, sd=1, shape=K)

    alpha = pm.Deterministic('alpha', pm.math.exp(a + tt.outer(T_data_z, b)))

    p = pm.Dirichlet('p', a=alpha, shape=(N, K))

    F = pm.Multinomial('F', 1, p, observed=F_data)

    trace = pm.sample(5000, tune=10000, target_accept=0.9)
示范成果 这个模型中的采样并不完美。例如,即使增加了目标接受率和额外调整,仍然存在许多分歧

调谐后有501个发散。增加
target\u accept
或重新参数化

调谐后有477个发散。增加
target\u accept
或重新参数化

接受概率与目标不匹配。它是0.5858954056820339,但应该接近0.8。尝试增加调整步骤的数量

某些参数的有效样本数小于10%

迹线图 我们可以看到
a
b
的轨迹看起来不错,平均位置与数据相符

配对图 虽然相关性对坚果来说不是什么问题,但不相关的后验抽样是理想的。在大多数情况下,我们看到相关性较低,在
a
组件中有一些轻微的结构

后验图 最后,我们可以查看
p
的后验图,并确认它们与数据相符


替代模型 Dirichlet多项式的优点是处理过度分散。可能值得尝试更简单的多项式逻辑回归/Softmax回归,因为它运行速度明显更快,并且不会出现DMR模型中出现的任何采样问题

最后,您可以运行这两个函数并执行模型比较,以查看Dirichlet多项式是否真的增加了解释值

模型 后验图

它看起来像
alpha = exp(beta*X)
import numpy as np
import pymc3 as pm
import theano
import theano.tensor as tt
from sklearn.preprocessing import scale

T_data = np.array([10,12,14,80,90,95])

# standardize the data for better sampling
T_data_z = scale(T_data)

# transform to theano tensor, so it works with tt.outer
T_data_z = theano.shared(T_data_z)

F_data = np.array([
    [0,0,1],
    [0,0,1],
    [0,0,1],
    [1,0,0],
    [1,0,0],
    [1,0,0],
])

# N = num_obs, K = num_components
N, K = F_data.shape

with pm.Model() as dmr_model:
    a = pm.Normal('a', mu=0, sd=1, shape=K)
    b = pm.Normal('b', mu=0, sd=1, shape=K)

    alpha = pm.Deterministic('alpha', pm.math.exp(a + tt.outer(T_data_z, b)))

    p = pm.Dirichlet('p', a=alpha, shape=(N, K))

    F = pm.Multinomial('F', 1, p, observed=F_data)

    trace = pm.sample(5000, tune=10000, target_accept=0.9)
with pm.Model() as softmax_model:
    a = pm.Normal('a', mu=0, sd=1, shape=K)
    b = pm.Normal('b', mu=0, sd=1, shape=K)

    p = pm.Deterministic('p', tt.nnet.softmax(a + tt.outer(T_data_z, b)))

    F = pm.Multinomial('F', 1, p, observed = F_data)

    trace_sm = pm.sample(5000, tune=10000)