我将分层模型拟合到某些数据中,拟合似乎可以接受。
with pm.Model() as model:
mu_a = pm.Normal('mu_a', 0, sd=.2)
sigma_b = pm.HalfNormal('sig_a', 0.1)
mean = pm.Normal('mean', mu_a, sigma_b, shape=n)
std = pm.HalfNormal('std', 0.01 , shape=n)
means = mean[h]
stds = std[h]
y = pm.Laplace('y', mu=means, b=stds, observed=data)
hierarchical_trace = pm.sample(2000, n_init=30000)
当检查后验预测时,尾部似乎合理,数据的最小值和最大值(黑线)似乎都在生成样本的最小值/最大值内(StudentT不是这种情况)。
ppc_trace = pm.sample_ppc(model=model, trace=hierarchical_trace)
ppc with min/max/mean of original data
然而,平均值(最右边的图表)是偏离的,我认为这是因为我的数据是负面偏斜的,所以数据的质量将平均值移到了太远的右边。
sp.stats.skew(data)
-0.1699020117521286
Pymc3建议的方法是对这类数据进行建模。虽然它是一个对称的分布拉普拉斯似乎很适合我的数据。高斯没有在尾部提供足够的重量(排除偏斜正常吗?)。如何对这种适度偏斜的数据进行建模?
我的目标是获得准确的MAP估计值,并为我的数据的不同部分提供可靠的间隔(基于分层规范)
答案 0 :(得分:1)
橡胶躲过了这个......但是对于任何后来磕磕绊绊的人都要回答
我发现asymmetric laplace很好地解决了不适合的问题。
def asym_laplace_log_p(x, m, lam, k):
diff = x - m
s = tt.sgn(diff)
return tt.log(lam / (k + 1 /k)) + ( - diff * lam * s * tt.pow(k, s))
def asym_laplace_cdf(x, m, lam, k):
diff = x - m
k_2 = k ** 2
if x <= m:
return (k_2 / (1 + k_2)) * np.exp((lam / k) * diff)
return 1 - ((1 / (1 + k_2)) * np.exp(-1 * lam * k * diff))
def inverse_cdf(u, m, lam, k):
s = np.sign(u)
k_s = np.power(k, s)
return m - (1/ (lam * s * k_s)) * np.log(u * s * k_s)
def asym_laplace_mean(m, lam, k):
return m + ((1 - k** 2) / (lam * k))
然后在模型中
y = pm.DensityDist('y', lambda x: asym_laplace_dist(x, means, stds, k), testval=0, observed=data)
cdf,反向cdf和仅用于调试目的,值得注意的是这个实现使用lambda作为形状而不是1 / lambda所以我发现前半径比原始问题中的半正常工作更好。
很高兴听到有关此实施的反馈意见。
在撰写本文时,密度dist不适用于sample_ppc(“AttributeError:'DensityDist'对象没有属性'random'”)所以我最终可能会使用生成的位置生成我自己的样本,形状和偏斜值。
我不认为这完全是犹太人的,所以很高兴看到这方面的一些方向(或解决这个问题的方向并直接使用sample_ppc)。