2017-04-26 81 views
2

我正在對某些數據擬合分層模型,擬合似乎可以接受。如何擬合pymc3中呈現歪斜的數據

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) 

當檢查後預測尾部似乎是合理的,min,並且數據的最大值(黑線)都似乎是最小/最大生成的樣本的內部(這是不與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到這類數據進行建模推薦的方法。雖然它是一個對稱分佈,但拉普拉斯似乎非常適合我的數據。高斯不會在尾部提供足夠的重量(這會排除偏斜正常?)。我如何模擬這種適度偏斜的數據?

我的目標是獲得一個準確的地圖估計與我的數據的不同部分可信區間(基於分級規範)

回答

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 /λ,所以我發現了一個半柯西因爲先前的形狀比原始問題中的半正常工作更好。

很高興聽到有關此實施的反饋意見。

在撰寫本文時,密度dist不適用於sample_ppc(「AttributeError:'DensityDist'對象沒有屬性'random'」),所以我最終可能會使用生成的位置通過上述生成我自己的樣本,形狀和偏斜值。

我不認爲這完全是猶太教,所以會很高興這個方向(或解決這個問題的方向和直接使用sample_ppc)。