## MCMC_MH 对连续和离散函数应用实例

1 篇文章 0 订阅

MCMC_MH 对连续和离散函数应用实例

MCMC_MH 对离散函数采样

离散函数采样来自作者kissmeanus
https://blog.csdn.net/kissmeanus/article/details/89073551

'''
Pi:输入概率分布,离散情况采用元素为概率值的数组表示
N:认为迭代N次马尔可夫链收敛
Nlmax:马尔可夫链收敛后又取的服从p分布的样本数
isMH:是否采用MH算法,默认为True
'''
import matplotlib.pyplot as plt
import numpy as np
from array import array


def mcmc(P,Q,N = 1000, Nlmax = 100000, isMH = False):
    T = N + Nlmax - 1
    result = [0 for i in range(T)]
    X0 = np.random.randint(len(P))
    result[0] = X0
    t = 0
    while t < T - 1:#还需要采样T-1次
        t = t+1
        x_cur = np.argmax(np.random.multinomial(1,Q[result[t-1]]))
        if isMH:
            a = (P[x_cur] * Q[x_cur][result[t-1]]) / (P[result[t-1]] * Q[result[t-1]][x_cur])
            acc = min(1,a)
        else:
            acc = min(1,P[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]
    result_chuli = result[N:]
    return result_chuli

def count(a, n):
    l1 = array('d')
    l2 = array('d')
    l3 = array('d')
    for e in a:
        l1.append(e)
    for e in range(n):
        l2.append(l1.count(e))
    for e in l2:
        l3.append(e/sum(l2))
    return l2,l3
    
if __name__ == '__main__':
    Pi = [0.2,0.3,0.5]
    Q = np.array([[0.2,0.3,0.5],
                  [0.2,0.3,0.5],
                  [0.2,0.3,0.5]])
    a = mcmc(Pi,Q,isMH = True)
    
    #最后用饼图来表述所采样本与目标函数Pi之间的关系
    l1 = count(a, len(Pi))[0]#l1获得各个状态的次数
    l2 = ['state%d' % x for x in range(len(Pi))]
    explode_list = [0,0.05,0]
    plt.pie(l1, labels= l2, labeldistance= 0.1, explode=explode_list, autopct='%0.2f%%')
    plt.legend()
    plt.show()

在这里插入图片描述

MCMC_MH 对连续函数进行采样

'''
MCMC_MH 对连续函数进行采样
Pi:输入概率分布,离散情况采用元素为概率值的数组表示
N:认为迭代N次马尔可夫链收敛
Nlmax:马尔可夫链收敛后又取的服从p分布的样本数
isMH:是否采用MH算法,默认为True
连续函数采样中的状态转移矩阵Q
'''
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats

def Pi_hanshu(x, loc= 0, scale= 1):
    '''
    目标函数
    '''
    Pi = scipy.stats.norm.pdf(x, loc=loc,scale=scale)
    return Pi
def mcmc(N=1000, Nlmax=100000, isMH=False):
    T = N + Nlmax - 1
    result = [0 for i in range(T)]
    X0 = scipy.stats.norm.rvs(loc=0, scale=1, size= 1)
    result[0] = X0[0]
    t = 0
    while t < T - 1:
        t += 1
        x_cur = (scipy.stats.norm.rvs(loc=result[t-1], scale= 1, size= 1))[0]
        if isMH:
            a = (Pi_hanshu(x_cur) * (scipy.stats.norm.pdf(x_cur,loc=result[t-1], scale= 1)))\
                / (Pi_hanshu(result[t-1]) * (scipy.stats.norm.pdf(result[t-1], loc=x_cur, scale= 1)))
            acc = min(1,a)
        else:
            acc = min(1,Pi_hanshu(x_cur) * scipy.stats.norm.pdf(x_cur, loc=result[t-1], scale= 1))
        u = np.random.uniform(0,1)
        if u < acc:
            result[t] = x_cur
        else:
            result[t] = result[t-1]
    result_chuli = result[N:]
    return result_chuli

def dia_scatter(a):
    x = [i for i in range(len(a))]
    plt.scatter(x, a, marker='x', c='r')
    plt.show()

if __name__ == '__main__':
    a = mcmc()
    
	最后用散点图来表示所采样本与目标函数N(0,1)之间的关系
    dia_scatter(a)
从图上可以看出,所采样本围绕x轴服从N(0,1)分布

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值