我试图了解以下代码的问题:
import pymc3 as pm
import theano as t
X = t.shared(train_new)
features = list(map(str, range(train_new.shape[1])))
with pm.Model() as logistic_model:
glm = pm.glm.GLM(X, targets, labels=features,
intercept=False, family='binomial')
trace = pm.sample(3000, tune=3000, jobs=-1)
数据集并不重要:它的形状为(891, 13)
。以下是我自己总结的结论:
theano.shared
,因为如果我删除它,性能又是一样的; pymc3.glm.GLM
中,因为当我手动构建模型时(可能比GLM
中的模型更简单),性能同样糟糕:
with pm.Model() as logistic_model:
invlogit = lambda x: 1 / (1 + pm.math.exp(-x))
σ = pm.HalfCauchy('σ', beta=2)
β = pm.Normal('β', 0, sd=σ, shape=X.get_value().shape[1])
π = invlogit(tt.dot(X, β))
likelihood = pm.Bernoulli('likelihood', π, observed=targets)
从约200 it/s
开始,很快就会降至5 it/s
。半采样后,它进一步减少到2 it/s
左右。这是一个严重的问题,因为该模型几乎没有收集成千上万的样本。我需要执行比这种情况目前更多的样本。
这是日志:
Auto-assigning NUTS sampler...
Initializing NUTS using jitter+adapt_diag...
99%|█████████▊| 5923/6000 [50:00<00:39, 1.97it/s]
我尝试使用pm.Metropolis()
作为步骤,它有点快,但它并没有收敛。
MWE :一个显示问题的最小工作示例的文件,数据在此处: https://gist.github.com/rubik/74ddad91317b4d366d3879e031e03396
答案 0 :(得分:4)
模型的非居中版本应该可以更好地运作:
β_raw = pm.Normal('β_raw', 0, sd=1, shape=X.get_value().shape[1])
β = pm.Deterministic('β', β_raw * σ)
如果有效样本量很小,通常你的第一个冲动不应该只是增加样本数量,而是尝试稍微使用参数化。
此外,您可以使用tt.nnet.sigmoid
代替您的自定义invlogit,它可能更快/更稳定。