Python可视化解析MCMC

本文介绍了马尔可夫链的概念,通过可视化展示状态转移,并探讨了不变分布及其在马尔可夫链蒙特卡罗(MCMC)方法中的作用。文章提供Python代码示例,模拟马尔可夫链并生成随机过程,展示如何通过MCMC方法抽样难以直接采样的分布。
摘要由CSDN通过智能技术生成

点击阅读原文,查看精彩日程!

作者 | Valentina Alto
译者 | 陆离
出品 | Python大本营(ID:pythonnews)

马尔可夫链(Markov Chain),又称为离散时间马尔可夫链,可以定义为一个随机过程Y,在某时间t上的任何一个点的值仅仅依赖于在时间t-1上的值。这就表示了我们的随机过程在时间t上具有状态x的概率,如果给出它之前所有的状态,那么就相当于在仅给出它在时间t-1的状态的时候,在时间t上具有状态x的概率。

640?wx_fmt=png

如果可能的状态集S是有限的,那么,我们可以提供马尔可夫链的可视化表示结果,如下图所示:

640?wx_fmt=png

上图中的每个圆圈都代表了一个状态,在这种情况下S={A, B, C},而箭头则表示过程从一个状态跳到另一个状态的概率。我们可以在一个称为“转移矩阵”P中收集所有的这些概率数据,如下图所示:

640?wx_fmt=png

那么,就有:

640?wx_fmt=png

然后,在每个时间点上,我们可以描述过程的(无条件的)概率分布,这将是一个向量,其分量数等于S的维数。每个分量表示我们的过程取值等于给定状态的无条件概率。也就是:

以下是Python实现Dream MCMC的基本步骤: 1. 定义目标函数,即需要采样的分布。 2. 初始化模型参数,并定义参数的先验分布。 3. 初始化多个马尔可夫链,每个链都有自己的参数值。 4. 每个链都进行一次随机游走,即使用差分进化算法更新参数值。 5. 计算每个链的接受概率,并根据概率接受或拒绝新的参数值。 6. 根据每个链的接受与否,更新其他链的参数值。 7. 重复步骤4-6,直到满足停止准则(如达到最大迭代次数或链的自相关系数小于某个阈值)。 以下是一个简单的Python实现Dream MCMC的代码示例: ```python import numpy as np from scipy.stats import norm # 定义目标分布,这里以正态分布为例 def target_logpdf(x): return norm.logpdf(x, loc=0, scale=1) # 定义先验分布,这里使用均匀分布 def prior_logpdf(x): return np.log(1 / (10 * np.sqrt(2 * np.pi))) - 0.5 * (x ** 2 / 10 ** 2) # 定义差分进化算法 def differential_evolution(chain, target_logpdf, prior_logpdf, scale=0.1): n_chains, n_params = chain.shape # 随机选择三个不同的链 idxs = np.random.choice(n_chains, size=(3, n_chains), replace=True) # 计算新的候选参数值 candidates = chain[idxs[0]] + scale * (chain[idxs[1]] - chain[idxs[2]]) # 计算接受概率 logprobs = target_logpdf(candidates) + prior_logpdf(candidates) - target_logpdf(chain) - prior_logpdf(chain) accept = logprobs > np.log(np.random.uniform(size=n_chains)) # 更新参数值 chain = np.where(accept[:, np.newaxis], candidates, chain) return chain # 定义Dream MCMC算法 def dream_mcmc(n_chains, n_params, target_logpdf, prior_logpdf, n_iterations=1000, burn_in=100): # 初始化模型参数 chain = np.random.normal(size=(n_chains, n_params)) # 初始化马尔可夫链的缩放因子 scales = np.ones(n_chains) # 迭代Dream MCMC算法 for i in range(n_iterations): # 使用差分进化算法更新参数值 chain = differential_evolution(chain, target_logpdf, prior_logpdf, scale=0.01 * scales) # 计算每个链的接受概率,并根据概率接受或拒绝新的参数值 logprobs = target_logpdf(chain) + prior_logpdf(chain) accept_probs = np.exp(logprobs - np.max(logprobs)) accept = np.random.uniform(size=n_chains) < accept_probs # 更新缩放因子 scales = np.where(accept, scales * 2, scales / 2) # 根据每个链的接受与否,更新其他链的参数值 idxs = np.random.choice(n_chains, size=n_chains, replace=True) chain[idxs] = np.where(accept[idxs, np.newaxis], chain, chain[idxs]) # 输出采样结果 if i >= burn_in and i % 100 == 0: print("Iteration", i, "Acceptance rate", np.mean(accept)) return chain # 运行Dream MCMC算法 chain = dream_mcmc(n_chains=10, n_params=1, target_logpdf=target_logpdf, prior_logpdf=prior_logpdf) ``` 以上代码仅供参考,实际使用时需要根据具体问题进行修改和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值