python贝叶斯模型_用 Python 进行贝叶斯模型建模(2)

原标题:用 Python 进行贝叶斯模型建模(2)

编译:伯乐在线 - JLee

《第 2 节:模型检验》

第2节:模型检验

在这一节中,我们将用到两种技术,旨在回答:

模型和估计的参数是否对潜在数据有很好的模拟?

给定两个独立的模型,哪个对潜在数据模拟的更好?

模型检验I:后验估计检验

一种检验模型拟合的方法是后验估计检验。这种方法很直观,回顾上节中,我们通过收集 200,000 个 μ 的后验分布样本来对泊松分布的参数 μ进行估计,每个样本都被认为是可信的参数值。

后验预测检验需要从预测模型中产生新的数据。具体来说就是,我们已经估计了 200,000 个可信的泊松分布参数值μ,这意味着我们可以根据这些值建立 200,000 个泊松分布,然后从这些分布中随机采样。用公式表示为:

理论上,如果模型对潜在数据拟合的很好,那么产生的数据应该和原始观测数据近似。PyMC 提供一种方便的方式来从拟合模型中采样。你可能已经注意到了上面模型应用中新的一行代码:

y_pred = pm.Poisson('y_pred', mu=mu)

这几乎和 y_est 一样,只不过没给观测数据赋值。PyMC 把它当做随机节点(和观测节点相反),当 MCMC 采样器运行时,它也从 y_est 中采集数据。

然后画出y_pred并和观测数据y_est比较。

importjson

importmatplotlib.pyplotasplt

importnumpyasnp

importpandasaspd

importpymc3aspm

importscipy

importscipy.statsasstats

importstatsmodels.apiassm

importtheano.tensorastt

fromIPython.displayimportImage

%matplotlibinline

plt.style.use('bmh')

colors=['#348ABD','#A60628','#7A68A6','#467821','#D55E00',

'#CC79A7','#56B4E9','#009E73','#F0E442','#0072B2']

messages=pd.read_csv('data/hangout_chat_data.csv')

Appliedinterval-transform to muandadded transformed mu_interval tomodel.

[-----------------100%-----------------]200000of200000completein63.5sec

x_lim=60

burnin=50000

y_pred=trace[burnin:].get_values('y_pred')

mu_mean=trace[burnin:].get_values('mu').mean()

fig=plt.figure(figsize=(10,6))

fig.add_subplot(211)

_=plt.hist(y_pred,range=[0,x_lim],bins=x_lim,histtype='stepfilled',color=colors[1])

_=plt.xlim(1,x_lim)

_=plt.ylabel('Frequency')

_=plt.title('Posterior predictive distribution')

fig.add_subplot(212)

_=plt.hist(messages['time_delay_seconds'].values,range=[0,x_lim],bins=x_lim,histtype='stepfilled')

_=plt.xlabel('Response time in seconds')

_=plt.ylabel('Frequency')

_=plt.title('Distribution of observed data')

plt.tight_layout()

选择正确的分布

我对上面的结果不是很满意。理想情况下,我希望后验预测分布和观测数据的分布一定程度上近似。直观上,如果我们正确估计了模型参数,那么我们应该可以从模型中采样得到类似的数据。结果很明显不是这样。

可能泊松分布不适合拟合这些数据。一种可选模型是负二项分布,特点和泊松分布很像,只是有两个参数(μ 和 α),使得方差和均值独立。回顾泊松分布只有一个参数 μ,既是均值,又是方差。

fig=plt.figure(figsize=(10,5))

fig.add_subplot(211)

x_lim=70

mu=[15,40]

foriinnp.arange(x_lim):

plt.bar(i,stats.poisson.pmf(mu[0],i),color=colors[3])

plt.bar(i,stats.poisson.pmf(mu[1],i),color=colors[4])

_=plt.xlim(1,x_lim)

_=plt.xlabel('Response time in seconds')

_=plt.ylabel('Probability mass')

_=plt.title('Poisson distribution')

_=plt.legend(['$lambda$ = %s'%mu[0],

'$lambda$ = %s'%mu[1]])

# Scipy takes parameters n & p, not mu & alpha

defget_n(mu,alpha):

return1./alpha*mu

defget_p(mu,alpha):

returnget_n(mu,alpha)/(get_n(mu,alpha)+mu)

fig.add_subplot(212)

a=[2,4]

foriinnp.arange(x_lim):

plt.bar(i,stats.nbinom.pmf(i,n=get_n(mu[0],a[0]),p=get_p(mu[0],a[0])),color=colors[3])

plt.bar(i,stats.nbinom.pmf(i,n=get_n(mu[1],a[1]),p=get_p(mu[1],a[1])),color=colors[4])

_=plt.xlabel('Response time in seconds')

_=plt.ylabel('Probability mass')

_=plt.title('Negative Binomial distribution')

_=plt.legend(['$mu = %s, / beta = %s$'%(mu[0],a[0]),

'$mu = %s, / beta = %s$'%(mu[1],a[1])])

plt.tight_layout()

使用之前相同的数据集,继续对负二项分布的参数进行估计。同样地,使用均匀分布来估计 μ 和 α。模型可以表示为:

代码:

Image('graphics/Neg Binomial Dag.png', width=400)

withpm.Model()asmodel:

alpha=pm.Exponential('alpha',lam=.2)

mu=pm.Uniform('mu',lower=0,upper=100)

y_pred=pm.NegativeBinomial('y_pred',mu=mu,alpha=alpha)

y_est=pm.NegativeBinomial('y_est',mu=mu,alpha=alpha,observed=messages['time_delay_seconds'].values)

start=pm.find_MAP()

step=pm.Metropolis()

trace=pm.sample(200000,step,start=start,progressbar=True)

Appliedlog-transformtoalphaandadded transformed alpha_logtomodel.

Appliedinterval-transformtomuandadded transformed mu_intervaltomodel.

[-----------------100%-----------------]200000of200000completein114.8sec

_ = pm.traceplot(trace[burnin:], varnames=['alpha', 'mu'])

我们看到上面的模型在平均回复时间 μ 附近有更大的不确定度:

泊松分布:17.5 到 18.5

负二项分布:16 到 21

同时,负二项分布模型有一个 1.4 到 2.4 的 α 参数,增加了估计参数 μ 的方差。让我们看看后验预测分布,是否和观测数据更加近似。

x_lim=60

y_pred=trace[burnin:].get_values('y_pred')

fig=plt.figure(figsize=(10,6))

fig.add_subplot(211)

fig.add_subplot(211)

_=plt.hist(y_pred,range=[0,x_lim],bins=x_lim,histtype='stepfilled',color=colors[1])

_=plt.xlim(1,x_lim)

_=plt.ylabel('Frequency')

_=plt.title('Posterior predictive distribution')

fig.add_subplot(212)

_=plt.hist(messages['time_delay_seconds'].values,range=[0,x_lim],bins=x_lim,histtype='stepfilled')

_=plt.xlabel('Response time in seconds')

_=plt.ylabel('Frequency')

_=plt.title('Distribution of observed data')

plt.tight_layout()

是的,和另一个相比,这两个分布看起来更近似。根据后验预测检验,负二项分布模型对潜在数据模拟更好。

如果你怀疑这种模型检验方法的严密性,贝叶斯方法还有一种更严密的分析方法。

模型检验II:贝叶斯因子

另一种模型检验的方法是计算贝叶斯因子,这种分析方法旨在两个模型间的相互比较。

贝叶斯因子通常难以计算,因为需要整合全联合概率分布。在低维空间中,整合是可能的,但是一旦你稍微增加建模的维度,整合全联合概率分布的计算会变得昂贵且费时。

有一种可选的近似方法来计算贝叶斯因子。它需要把两个模型进行比较,把它们融合成一个带有一个模型指数(τ)的分层模型.这个指数在MCMC 过程中,会根据模型的可信度在两个模型中切换,这样,这个指数的轨迹就充分显示模型 M1 相对模型 M2 的可信度。

Image('graphics/Bayes Factor DAG.png', width=540)

withpm.Model()asmodel:

# Index to true model

prior_model_prob=0.5

#tau = pm.DiscreteUniform('tau', lower=0, upper=1)

tau=pm.Bernoulli('tau',prior_model_prob)

# Poisson parameters

mu_p=pm.Uniform('mu_p',0,60)

# Negative Binomial parameters

alpha=pm.Exponential('alpha',lam=0.2)

mu_nb=pm.Uniform('mu_nb',lower=0,upper=60)

y_like=pm.DensityDist('y_like',

lambdavalue:pm.switch(tau,

pm.Poisson.dist(mu_p).logp(value),

pm.NegativeBinomial.dist(mu_nb,alpha).logp(value)

),

observed=messages['time_delay_seconds'].values)

start=pm.find_MAP()

step1=pm.Metropolis([mu_p,alpha,mu_nb])

step2=pm.ElemwiseCategoricalStep(vars=[tau],values=[0,1])

trace=pm.sample(200000,step=[step1,step2],start=start)

_=pm.traceplot(trace[burnin:],varnames=['tau'])

Appliedinterval-transform to mu_pandadded transformed mu_p_interval tomodel.

Appliedlog-transform to alphaandadded transformed alpha_log tomodel.

Appliedinterval-transform to mu_nbandadded transformed mu_nb_interval tomodel.

[-----------------100%-----------------]200000of200000completein314.6sec

根据下面的公式计算上面两个模型的贝叶斯因子:

在上例中,我们没有使用先验概率,因此贝叶斯因子只是模型似然度的商。如果你发现你的 MCMC 样本不在两个模型间游走,你可以引入先验概率来帮助你更深入了解两个模型。

# Compute the Bayes factor

prob_pois=trace[burnin:]['tau'].mean()

prob_nb=1-prob_pois

BF=(prob_nb/prob_pois)*(prior_model_prob/(1-prior_model_prob))

print("Bayes Factor: %s"%BF)

Bayes Factor: 1.60114103387

贝叶斯因子大于 1 说明 M1(负二项分布)比 M2(泊松分布)更适合拟合数据。Jeffrey的贝叶斯因子优势判别准则把贝叶斯因子为 1.60 标识为 M1 对 M2 有弱优势。结合后验预测检验和贝叶斯因子,可得出结论:负二项分布模型更优。

责任编辑:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值