c语言编程笔录

首页 >   > 笔记大全

笔记大全

gibbs采样代码python多维gibbs采样实例

更新时间:2023-10-03

前言

在贝叶斯统计中,目标是寻找一个后验分布,即给定观测值后参数的分布。然而,由于许多模型的后验分布无法解析计算,因此需要使用MCMC方法来获得后验分布的近似。 Gibbs采样是一种非常常见且受欢迎的MCMC方法之一。 Gibbs采样方法通过逐个条件子分量的抽样替代所有分量同时抽样的策略,这对于许多问题来说是非常有用的。在这篇文章中,我们将介绍如何使用Python编写Gibbs采样算法。同时,我们将提供一个多维Gibbs采样的例子来说明如何使用该算法。

代码示例 1

Gibbs采样算法的基本原理是从后验分布的条件分布中抽样,而不是从全体后验分布中抽样。

def gibbs_sampling(posterior, initial_value, num_samples):
    """
    Gibbs采样算法实现函数,输出指定数量的样本。
       
    参数:
    posterior : 函数类型,用于计算后验分布的对数,参数为关于待抽样参数的数组。
    initial_value : 初始值列表。
    num_samples : 所需样本数。

    返回:
    samples : num_samples数量的样本列表。
    """
    # 获取参数数量
    num_params = len(initial_value)
    # 初始化样本空数组
    samples = np.zeros((num_samples, num_params))
    # 初始化起始值
    current_sample = initial_value
    
    # 开始采样
    for i in range(num_samples):
        # 在后验分布的条件概率分布中抽样
        for j in range(num_params):
            # 从条件概率分布中抽样
            current_sample[j] = np.random.normal(loc=current_sample[:j].sum()+current_sample[j+1:].sum(),
                                              scale=posterior(current_sample[:j]+current_sample[j+1:]+[0])/posterior(current_sample))
        # 将采样的样本存储
        samples[i,:] = current_sample
        
    return samples

代码示例 2

下面我们来看一下如何使用Gibbs采样算法来进行多维抽样。我们将使用Gibbs采样算法来从二维“双月亮”分布中抽样。先导入一些必要的包:

import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import multivariate_normal, norm

然后,我们可以定义双月亮分布的概率密度函数:

def bimodal_pdf(x, y):
    return .5*(multivariate_normal.pdf([x, y], mean=[1,0], cov=[[2,1],[1,2]]) 
              + multivariate_normal.pdf([x, y], mean=[-1,0], cov=[[2,1],[1,2]]))

接下来,我们可以定义一个gibbs_sampler函数来使用Gibbs采样返回指定数量的样本:

def gibbs_sampler(num_samples=100, x_start=0, y_start=0):
    samples = np.zeros((num_samples,2))
    x, y = x_start, y_start
    for i in range(num_samples):
        x = norm.rvs(loc=y, scale=1)
        y = norm.rvs(loc=x, scale=1)
        samples[i,:] = [x,y]
    return samples

最后,我们调用gibbs_sampler函数,采样num_samples个样本,绘制结果图表:

num_samples = 5000
samples = gibbs_sampler(num_samples=num_samples, x_start=-2, y_start=3)

plt.scatter(samples[:,0], samples[:,1], alpha=.4, s=3)
plt.xlim(-5,5)
plt.ylim(-5,5)
plt.title('Gibbs Sampler for Bimodal Distribution')
plt.show()

代码示例 3

除此之外,我们也可以用多个Gibbs采样函数实现多维数据的采样。下面是一个多元高斯分布的Gibbs采样实例:

def gaussian_sampler(num_samples=10000, mu=[0,0], sigma=[[1,0],[0,1]]):
    """
    用Gibbs采样进行多元高斯分布的抽样。

    参数:
     mu : 指定高斯分布的均值。
     sigma : 指定高斯分布的协方差矩阵。

    返回:
     返回一个两维的样本数组。
    """
    x_initial = np.zeros(2)
    x = np.zeros(2)
    samples = np.zeros((num_samples, 2))

    for i in range(num_samples):
        x[0] = np.random.normal(mu[0] + sigma[0][1]*x_initial[1]/sigma[1][1], 
                                np.sqrt(sigma[0][0] - sigma[0][1]*sigma[1][0]/sigma[1][1]))
        x[1] = np.random.normal(mu[1] + sigma[1][0]*x[0]/sigma[0][0], 
                                np.sqrt(sigma[1][1] - sigma[1][0]*sigma[0][1]/sigma[0][0]))
        samples[i,:] = x
        x_initial = x

    return samples

总结

本文介绍了Gibbs采样的基本原理以及如何使用Python实现该算法。我们还提供了一个使用Gibbs采样来抽样一个二维“双月亮”分布的例子以及一个多元高斯分布的示例。无论是在数学、物理、统计模型还是计算机科学系统中,Gibbs采样都是一个重要的工具,它可以产生样本并估计后验概率分布。在进行任何MCMC建模之前,Gibbs的将是我们需要重点考虑的算法之一。