MCMC算法

一. MCMC算法定义

    MCMC是Markov chain Monte Carlo的缩写,即马尔可夫链蒙特卡罗方法。MCMC是一组利用马尔可夫链从随机分布中取样的算法。生成的马氏链即是对于目标分布的近似估计。

常见算法:

  • Metropolis-Hastings算法
  • Gibbs取样算法
  • Hamiltonian Monte Carlo算法(效率最高,但不常用)
    在统计推断和贝叶斯推断中,常用的是前两种算法。

二、Metropolis算法

假设随机变量X服从一个概率密度函数P。

  1. 初始化X,即给定随机变量一个起始点 X o l d X_{old} Xold
  2. 生成随机的跳跃 Δ X \Delta X ΔX~ N ( 0 , σ ) N(0,\sigma) N(0,σ) X n e w = X o l d + Δ X X_{new} = X_{old}+\Delta X Xnew=Xold+ΔX
  3. 计算随机变量移动到提议的点的概率
    P m o v i n g = m i n ( 1 , X n e w X o l d ) P_{moving} = min(1, \frac{X_{new}} {X_{old}}) Pmoving=min(1,XoldXnew)
  4. 生成一个随机数 C C C~ U ( 0 , 1 ) U(0,1) U(0,1),如果 C < P m o v i n g C < P_{moving} C<Pmoving 则接受跳跃,随机变量取新的值 X n e w X_{new} Xnew;反之则任取原来的值。
  5. 重复步骤2~4,并记录下随机变量所有的取值,知道蒙特卡洛模拟生成的随机游走足以代表目标分布。

利用Gamma分布对Metropolis算法进行测试

# Metropolis算法
import numpy
from scipy.special import gamma
import scipy.stats
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def MCMC(P,X0,chain,space):
    '''
    P - 随机变量X服从的概率密度函数
    X0 - MCMC的起始值
    chain - MCMC的长度
    space - 随机变量的取值范围,如[0,inf]
    '''
    
    if not callable(P):
        raise Exception('P必须是函数')
        
    X_current = X0
    X = [X_current]
    
    while True:
        Delta_X = scipy.stats.norm(loc=0,scale=2).rvs()
        X_proposed = X_current + Delta_X
        
        if X_proposed < space[0] or X_proposed > space[1]:
            p_moving = 0
        elif P(X_current) == 0:
            p_moving = 1
        else:
            p_moving = min(1,P(X_proposed)/P(X_current))
            
        if scipy.stats.uniform().rvs() <= p_moving:  #新生成的服从0,1均匀分布的值小于等于p_moving
            X.append(X_proposed)
            X_current = X_proposed
        else:
            X.append(X_current)
            
        if len(X) >= chain:
            break
        
    return numpy.array(X)
# 测试Metropolis算法:生成服从Gamma分布的马氏链
def GammaDist(x,k,theta):
    '''定义Gamma分布'''
    return 1/(gamma(k)*theta**k) * x**(k-1) * numpy.exp(-x/theta)

# 得到参数k=2,theta=2的分布
gammadist = lambda x: GammaDist(x,2,2)

X = MCMC(gammadist,2,100,[0,numpy.inf])   #最终结果:有MCMC算法生成的马氏链

这里生成的X就是使用MCMC算法生成的近似服从Gamma分布,是对目标分布的近似估计。下面通过动画演示这一过程。

# 用一个动画来演示生成的马氏链
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(20, 10))
fig.suptitle('MCMC Process')


def anima_chain(index):
    ax1.clear()

    ax1.plot(X[:index + 1], 'r-')
    # ax1.set_xlim([1,1000])
    ax1.set_xlabel('chain')  # 第多少步
    ax2.set_label('X')  # 生成的马氏链

    # ax1.set_title('MCMC Process')


def anima_density(index):
    ax2.clear()

    x = numpy.arange(0., 12, .1)
    ax2.plot(x, gammadist(x), 'k-')
    if index <= 10:
        y = numpy.zeros(len(x))
        ax2.plot(x, y)
    else:
        density = scipy.stats.gaussian_kde(X[:index - 1])
        ax2.plot(x, density(x), 'r-')

    ax2.set_xlim([0.,12])
    ax2.set_ylim([0,.5])
    ax2.set_xlabel('X')
    ax2.set_ylabel('density')

    # ax2.set_title('MCMC density estimate')

ani_chain = animation.FuncAnimation(fig, anima_chain, interval=1)
ani_density = animation.FuncAnimation(fig, anima_density, interval=1)


def main():
    plt.show()

if __name__ == '__main__':
    main()

在这里插入图片描述

  • 左侧是MCMC算法每一次迭代生成的随机数得到的马氏链,不断地取下一个点;
  • 右边是根据模拟出来的chain来近似得到的概率密度曲线(红色曲线);
  • MCMC模拟出来的分布要近似于目标分布Gamma分布。
  • 生成1000个数后得到的马氏链,可以近似的拟合我们的真实分布Gamma(2,2)。如果我们将链拉的更长,那就这个生成的马氏链几乎可以完美的拟合真实分布。
  • 后续过程中,会不断根据两个信息(概率密度函数的信息-也就是每个采样点之间相关关系的信息,以及随机游走的信息)来更新马氏链,最终很好的拟合目标分布。
  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MCMC(Markov Chain Monte Carlo)算法是一种用于概率统计和贝叶斯推断的方法,常用于定价和模拟复杂的金融衍生品。它通过构建一个马尔可夫链来生成样本,从而近似计算目标分布的期望值。 在Python中,有一些常用的库可以用于实现MCMC算法,例如PyMC3和emcee。这些库提供了方便的接口和函数,使得使用MCMC算法进行定价变得相对简单。 下面是一个使用PyMC3库实现MCMC算法进行定价的示例: ```python import pymc3 as pm # 定义模型 with pm.Model() as model: # 定义参数 mu = pm.Normal('mu', mu=0, sd=1) sigma = pm.HalfNormal('sigma', sd=1) # 定义观测数据 obs = pm.Normal('obs', mu=mu, sd=sigma, observed=data) # 运行MCMC算法 trace = pm.sample(1000, tune=1000) # 获取参数估计值 mu_est = trace['mu'].mean() sigma_est = trace['sigma'].mean() # 输出结果 print("mu的估计值:", mu_est) print("sigma的估计值:", sigma_est) ``` 上述代码中,首先使用`pymc3.Model`定义了一个模型,然后通过`pm.Normal`和`pm.HalfNormal`定义了参数的先验分布,`pm.Normal`用于定义均值参数,`pm.HalfNormal`用于定义标准差参数。接着使用`pm.Normal`定义了观测数据的分布,并通过`observed`参数传入观测数据。最后使用`pm.sample`运行MCMC算法,得到参数的后验分布。 相关问题: 1. 什么是MCMC算法? 2. MCMC算法常用于哪些领域? 3. 除了PyMC3和emcee,还有哪些Python库可以实现MCMC算法? 4. MCMC算法的优缺点是什么? 5. MCMC算法的原理是什么?

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值