MCMC ,M-H采样 示例 (pyhton版本)

初看MCMC采样的时候,一脑子的雾水。不尽会问,马尔科夫链稳定后怎么采样啊,都稳定了每次采样出来的东西不是一样的吗?这时候特别希望有个例子能看看,怎么采样的,采出来的是什么东西。很不幸,网上的例子全是连续函数的版本的,没有离散版本的。那么今天,我就把我的代码分享给大家。

'''
Created on 2018年5月16日
p:输入的概率分布,离散情况采用元素为概率值的数组表示
N:认为迭代N次马尔可夫链收敛
Nlmax:马尔可夫链收敛后又取的服从p分布的样本数
isMH:是否采用MH算法,默认为True

1)输入我们任意选定的马尔科夫链状态转移矩阵Q,平稳分布π(x),设定状态转移次数阈值n1,需要的样本个数n2
2)从任意简单概率分布采样得到初始状态值x0
3)for t=0 to n1+n2−1:
 a) 从条件概率分布Q(x|xt)中采样得到样本x∗
 b) 从均匀分布采样u∼uniform[0,1]
 c) 如果u<α(xt,x∗)=π(x∗)Q(x∗,xt), 则接受转移xt→x∗,即xt+1=x∗
 d) 否则不接受转移,即xt+1=xt
样本集(xn1,xn1+1,...,xn1+n2−1)即为我们需要的平稳分布对应的样本集。
'''

from __future__ import division
import matplotlib.pyplot as plt
import numpy as np
from array import array

def mcmc(Pi ,Q,N=1000,Nlmax=100000,isMH=False):
    X0 = np.random.randint(len(Pi))# 第一步:从均匀分布(随便什么分布都可以)采样得到初始状态值x0
    T = N+Nlmax-1
    result = [0 for i in range(T)]
    t = 0
    while t < T-1:
        t = t + 1
        # 从条件概率分布Q(x|xt)中采样得到样本x∗
        # 该步骤是模拟采样,根据多项分布,模拟走到了下一个状态
        #(也可以将该步转换成一个按多项分布比例的均匀分布来采样)  
        x_cur = np.argmax(np.random.multinomial(1,Q[result[t-1]]))  # 第二步:取下一个状态 ,采样候选样本
        if isMH:
            '''
                细致平稳条件公式:πi Pij=πj Pji,∀i,j
            '''
            a = (Pi[x_cur] * Q[x_cur][result[t-1]]) /(Pi[result[t-1]] * Q[result[t-1]][x_cur])  # 第三步:计算接受率
            acc = min(a ,1)
        else: #mcmc
            acc = Pi[x_cur] * Q[x_cur][result[t-1]]
        u = np.random.uniform(0 ,1)  # 第四步:生成阈值
        if u< acc:  # 第五步:是否接受样本
            result[t]=x_cur
        else:
            result[t]= result[t-1]
    return result

def count(q, n):
    L = array("d")
    l1 = array("d")
    l2 = array("d")
    for e in q:
        L.append(e)
    for e in range(n):
        l1.append(L.count(e))
    for e in l1:
        l2.append(e / sum(l1))
    return l1, l2

if __name__ == '__main__':
    Pi = np.array([0.5, 0.2, 0.3]) # 目标的概率分布
    #状态转移矩阵,但是不满足在 平衡状态时和 Pi相符
    #我们的目标是按照某种条件改造Q ,使其在平衡状态时和Pi相符
    #改造方法就是,构造矩阵 P,且 P(i,j)=Q(i,j)α(i,j)
    #                          α(i, j) = π(j)Q(j, i)
    #                          α(j, i) = π(i)Q(i, j)
    Q = np.array([[0.9, 0.075, 0.025],
                  [0.15, 0.8, 0.05],
                  [0.25, 0.25, 0.5]])

    a = mcmc(Pi,Q)
    l1 = ['state%d' % x for x in range(len(Pi))]
    plt.pie(count(a, len(Pi))[0], labels=l1, labeldistance=0.3, autopct='%1.2f%%')
    plt.title("markov:" +str(Pi))
    plt.show()

可以看见。我们的转移概率矩阵Q的平衡状态是[0.61.0.31.0.8],和我们的目标分布 Pi [0.5, 0.2, 0.3]是不相同的,所以我们的目标是构造一个转移概率矩阵 P, P(i,j)=Q(i,j)α(i,j),使得P的平衡状态满足PI。代码的结果为:
结果图
由于mcmc采样效率低(接受率低),需要多采一点样本才看起来更像。

  • 9
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
M-H(Metropolis-Hastings)采样是一种马尔可夫链蒙特卡洛(MCMC)算法,用于从复杂的概率分布中进行采样。与Gibbs采样类似,M-H采样也是一种基于马尔可夫链的迭代采样方法。 M-H采样的思想是通过接受-拒绝的方式,从一个简单的提议分布中采样得到样本,并根据接受概率决定是否接受这个样本。具体步骤如下: 1. 初始化初始样本。 2. 从提议分布中抽取一个候选样本。 3. 计算接受概率(Acceptance Probability): - 计算当前样本在目标分布下的概率密度值(目标概率密度)。 - 计算候选样本在目标分布下的概率密度值。 - 计算接受概率为两个概率密度的比例乘以候选样本被提议分布抽取的概率密度。 4. 生成一个[0,1]之间的随机数。 5. 如果随机数小于等于接受概率,则接受候选样本作为下一个样本;否则,保持当前样本不变。 6. 重复步骤2到步骤5,直到达到预定的迭代次数或满足收敛条件。 M-H采样中的提议分布通常是一个简单的分布,如高斯分布。接受概率的计算允许采样从低概率区域向高概率区域移动,从而得到符合目标分布的样本。 需要注意的是,M-H采样的性能与提议分布的选择密切相关。如果提议分布过于简单,可能导致采样效率低下;如果提议分布与目标分布差异较大,可能导致高拒绝率。因此,在实际应用中,选择合适的提议分布是一个关键问题。 总之,M-H采样是一种常用的MCMC算法,用于从复杂的概率分布中进行采样,尤其适用于无法直接从目标分布中采样的情况。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值