现在假设我们正在查看两只股票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
然而,结果估计并没有给我带来不同的分布...我是否混淆了后验分布的概念?
答案 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。