Gibbs Gauss采样入门
引言
Gibbs采样是一种马尔可夫链蒙特卡洛(MCMC)方法,用于从一个高维的概率分布中采样。在多元统计学和机器学习领域广泛应用。本文将介绍Gibbs采样的概念和步骤,并通过一个简单的例子演示如何使用Gibbs采样来采样从高斯分布中。
Gibbs采样步骤
Gibbs采样适用于联合分布(conditional distribution)可解析求解的情况下。下面是Gibbs采样的基本步骤:
- 初始化模型参数:从联合分布中的任意初始点开始,得到一个初始的样本点。
- 对于每个参数,按照条件分布采样:通过固定其他参数的值,从条件分布中采样得到新的参数值。
- 重复步骤2,直到得到足够数量的样本点。
- 收集样本点:将步骤3中得到的样本点作为最终的采样结果。 下面将通过一个示例来展示如何使用Gibbs采样来从高斯分布中采样。
Gibbs采样示例:采样从高斯分布中
考虑一个二维的高斯分布: $$ P(x, y) = frac{1}{2pi sigma_{x}sigma_{y}sqrt{1-rho^2}} expleft(-frac{1}{2(1-rho^2)}left(frac{(x-mu_x)^2}{sigma_x^2} - frac{2rho(x-mu_x)(y-mu_y)}{sigma_xsigma_y} frac{(y-mu_y)^2}{sigma_y^2}right)right) $$ 其中,$x$和$y$是服从正态分布的随机变量,$mu_x, mu_y$分别是$x$和$y$的均值,$sigma_{x}, sigma_{y}$分别是$x$和$y$的标准差,$rho$是$x$和$y$的相关系数。 下面通过Gibbs采样来从上述二维高斯分布中采样。
步骤1:初始化参数
首先,我们初始化模型参数。选择一个任意的初始点 $(x_0, y_0)$。
代码语言:javascript复制pythonCopy codeimport numpy as np
# 初始化参数
mu_x = 2
mu_y = 2
sigma_x = 1
sigma_y = 1
rho = 0.5
# 初始化初始点
x0 = 0
y0 = 0
步骤2:按条件分布采样
待采样的二维高斯分布是联合分布,我们需要分别采样$x$和$y$这两个变量。根据高斯分布的特性,我们可以得到给定某个变量的条件下另一个变量的条件分布。 对于$x$: $$ P(x|y) = Nleft(mu_x rhofrac{sigma_x}{sigma_y}(y - mu_y), (1 - rho^2)sigma_x^2right) $$ 对于$y$: $$ P(y|x) = Nleft(mu_y rhofrac{sigma_y}{sigma_x}(x - mu_x), (1 - rho^2)sigma_y^2right) $$ 根据上述条件分布,我们可以分别得到给定$y_0$的条件下,采样$x_1$的值,以及给定$x_1$的条件下,采样$y_1$的值。
代码语言:javascript复制pythonCopy codedef sample_x_given_y(y, mu_x, mu_y, sigma_x, sigma_y, rho):
"""给定y的条件下,采样x"""
mu = mu_x rho * sigma_x / sigma_y * (y - mu_y)
sigma = np.sqrt((1 - rho ** 2) * sigma_x ** 2)
return np.random.normal(mu, sigma)
def sample_y_given_x(x, mu_x, mu_y, sigma_x, sigma_y, rho):
"""给定x的条件下,采样y"""
mu = mu_y rho * sigma_y / sigma_x * (x - mu_x)
sigma = np.sqrt((1 - rho ** 2) * sigma_y ** 2)
return np.random.normal(mu, sigma)
步骤3和4:重复采样和收集样本点
接下来,根据上述步骤2中得到的条件分布,进行重复采样,直到得到足够数量的样本点。
代码语言:javascript复制pythonCopy code# 重复采样并收集样本点
num_samples = 1000
samples = []
# 初始化样本点
x = x0
y = y0
# 重复采样
for _ in range(num_samples):
# 采样x
x = sample_x_given_y(y, mu_x, mu_y, sigma_x, sigma_y, rho)
# 采样y
y = sample_y_given_x(x, mu_x, mu_y, sigma_x, sigma_y, rho)
# 收集样本点
samples.append((x, y))
在上述代码中,重复采样了1000个样本点,并将其存储在samples
列表中。
结果可视化
最后,我们可以将采样结果绘制成散点图,用于可视化二维高斯分布的采样结果。
代码语言:javascript复制pythonCopy codeimport matplotlib.pyplot as plt
# 提取样本点的x和y值
x_samples = [s[0] for s in samples]
y_samples = [s[1] for s in samples]
# 绘制散点图
plt.scatter(x_samples, y_samples, alpha=0.6)
plt.title("Gibbs Sampling - Sampling from Bivariate Gaussian Distribution")
plt.xlabel("x")
plt.ylabel("y")
plt.show()
运行上述代码后,将会得到一个散点图,展示了从二维高斯分布中采样的结果。
结论
本文介绍了Gibbs采样的基本步骤,并通过一个简单的示例演示了如何使用Gibbs采样从二维高斯分布中进行采样。Gibbs采样是一种强大的采样方法,在统计学、机器学习等领域有广泛应用。通过了解和使用Gibbs采样,我们可以更好地理解和应用MCMC方法。
实际应用场景可以是一个学生成绩管理系统。下面是一个使用Python实现的示例代码:
代码语言:javascript复制pythonCopy codeclass Student:
def __init__(self, stu_id, name):
self.stu_id = stu_id # 学生学号
self.name = name # 学生姓名
self.scores = {} # 学生成绩字典,键为科目名,值为分数
def add_score(self, subject, score):
self.scores[subject] = score
def get_average_score(self):
if len(self.scores) == 0:
return 0
else:
total_score = sum(self.scores.values())
return total_score / len(self.scores)
class GradeManagement:
def __init__(self):
self.students = {} # 学生字典,键为学生学号,值为学生对象
def add_student(self, stu_id, name):
student = Student(stu_id, name)
self.students[stu_id] = student
def add_score(self, stu_id, subject, score):
if stu_id in self.students:
student = self.students[stu_id]
student.add_score(subject, score)
def get_student_average_score(self, stu_id):
if stu_id in self.students:
student = self.students[stu_id]
return student.get_average_score()
# 示例代码的使用
grade_management = GradeManagement()
# 添加学生
grade_management.add_student(1, "张三")
grade_management.add_student(2, "李四")
# 添加成绩
grade_management.add_score(1, "数学", 90)
grade_management.add_score(1, "英语", 85)
grade_management.add_score(2, "数学", 95)
grade_management.add_score(2, "英语", 92)
# 获取学生平均成绩
average_score_1 = grade_management.get_student_average_score(1)
average_score_2 = grade_management.get_student_average_score(2)
print("学生1的平均成绩:", average_score_1)
print("学生2的平均成绩:", average_score_2)
以上代码实现了一个简单的学生成绩管理系统,可以添加学生、添加成绩,并获取学生的平均成绩。
Gibbs采样是一种用于对多维概率分布进行采样的方法,它通过逐个变量更新的方式利用条件概率进行采样。虽然Gibbs采样在实际应用中有着广泛的应用,并且其算法简单易懂,但也存在一些缺点:
- 收敛速度慢:Gibbs采样通常需要进行多轮迭代才能得到准确的采样结果。尤其是当所采样的分布具有较高的维度时,收敛速度更加慢。
- 无法跳出局部极值:Gibbs采样是一种局部采样方法,每次迭代仅通过条件概率对一个变量进行更新。这种逐个变量更新的特性使得Gibbs采样容易陷入和停滞在局部极值点,无法快速获取全局最优解。
- 采样效率低:由于Gibbs采样每次仅更新一个变量,因此需要大量的迭代次数才能收敛。因而在实际应用中需要投入较多的计算资源和时间。 类似的方法包括Metropolis-Hastings采样和重要性采样。 Metropolis-Hastings采样是一种基于马尔可夫链的采样方法,通过引入接受-拒绝策略,可以在某些情况下跳出局部极值。相较于Gibbs采样,Metropolis-Hastings采样的优势是可以从一个概率分布中采样,而不仅限于条件概率分布。 重要性采样是一种通过引入权重的方式对概率分布进行采样的方法。它通过从一个已知的简单概率分布中采样,并利用被采样样本对目标分布进行加权,从而得到目标分布的采样。与Gibbs采样相比,重要性采样在一定程度上可以更有效地探索高概率区域,但也需要引入权重计算和进行权重调整,增加了计算复杂度。