使用PYMC3

时间:2018-01-25 07:57:31

标签: python pymc3

现在假设我们正在查看两只股票A和B的每日价格。前面很简单:价格都是正态分布的,mu_A和mu_B均匀分布在[10,100]上,sigma_A和sigma_B也均匀分布在[1,10]。 (我知道这些是一些天真/错误的假设 - 只是为了让问题更清楚。)

现在假设我已经观察了这两个股票一个月并收集了价格数据。我可以分别得到A和B的后验分布,但是如何得到两个股票之间差异的后验分布?

prices_A = [25,20,26,23,30,25]
prices_B = [45,49,52,58,45,48]
basic_model = pm.Model()
with basic_model: 
    mu_A = pm.Uniform('mu_A', lower=10, upper=100)
    sigma_A = pm.Uniform('sigma_A', lower=1, upper=10)
    mu_B = pm.Uniform('mu_B', lower=10, upper=100)
    sigma_B = pm.Uniform('sigma_B', lower=1, upper=10)
    A = pm.Normal('Y_1', mu=mu_A, sd=sigma_A, observed=prices_A)
    B = pm.Normal('Y_2', mu=mu_B, sd=sigma_B, observed=prices_B)
    dif = pm.Deterministic('dif', A-B)
map_estimate = pm.find_MAP(model=basic_model)
map_estimate

然而,结果估计并没有给我带来不同的分布...我是否混淆了后验分布的概念?

1 个答案:

答案 0 :(得分:1)

减去这两个变量,你可以在采样之后这样做:

C = trace['A'] - trace['B']

或者您可以使用确定性变量将其作为模型的一部分:

C = pm.Deterministic('C', A - B)

更新

现在您已发布模型,我将建议以下

prices_A = [25,20,26,23,30,25]
prices_B = [45,49,52,58,45,48]
basic_model = pm.Model()
with basic_model: 
    mu_A = pm.Uniform('mu_A', lower=10, upper=100)
    sigma_A = pm.Uniform('sigma_A', lower=1, upper=10)
    mu_B = pm.Uniform('mu_B', lower=10, upper=100)
    sigma_B = pm.Uniform('sigma_B', lower=1, upper=10)
    A = pm.Normal('Y_1', mu=mu_A, sd=sigma_A, observed=prices_A)
    B = pm.Normal('Y_2', mu=mu_B, sd=sigma_B, observed=prices_B)
    dif = pm.Deterministic('dif', mu_A-mu_B) # diff of the means
    trace = pm.sample()

 pm.summary(trace)

基本上我的建议是你不使用find_MAP(),而是从后验采样,然后从那些样本(在trace内)计算你想要的东西。例如,summary将给出平均值,标准偏差和从后验样本计算的其他数量。

您可能还想使用sample_ppc来获取"后验预测样本"。

ppc = pm.sample_ppc(trace, 1000, basic_model)
dif_ppc = ppc['Y_1'] - ppc['Y_2']

dif_ppc代表您期望看到的股票差异,包括平均值的不确定性和股票的标准差。

作为旁注,也许您想要通过其他分布替换您的Uniform分布,例如Normal用于均值和HalfNormals用于sigmas。