1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 简单易学!一步步带你理解机器学习算法——马尔可夫链蒙特卡罗(MCMC)

简单易学!一步步带你理解机器学习算法——马尔可夫链蒙特卡罗(MCMC)

时间:2022-11-18 10:52:16

相关推荐

简单易学!一步步带你理解机器学习算法——马尔可夫链蒙特卡罗(MCMC)

原文:/articles/66987#2

1什么是MCMC,什么时候使用它

MCMC只是一种从分布中抽样的算法。这个术语代表“马尔科夫蒙特卡罗”,因为它是一种使用了 “马尔科夫链”的“蒙特卡罗”(即随机)方法。MCMC只是一种蒙特卡罗方法。

(文中有些使用R语言实现的没有改动)

2为什么我要从分布抽样呢?

从分布抽烟是解决一些问题的最简单的方法

也许在贝叶斯推断中最常见的方式是使用MCMC从某些模型的后验概率分布中抽取样本。有了这些示例,你就可以问这样的问题:什么是参数的平均值和可信区间?”。

例如,加入你有合适的参数模型的后验概率密度是某个函数f(x,y)。然后,计算参数x的平均值,你可以这样计算

你可以简单的读作“x乘参数(x,y)的概率,积分在x和y可能采用的所有可能值上。”

另一种计算这个值得方法是模拟观察值K,

从f(x,y)计算样本平均值为

其中x(j)为第j个样本的x的值。如果这些样本是服从独立分布的样本,那么随着K趋于无穷大,x的估计平均值会收敛于真平均数。

假设我们的目标分布是一个正态分布,平均数为m,标准偏差为s。显然,这种分布的平均值是m,让我们试着通过从分布中抽取样本来显示。

例1估计一个平均值为m,标准差为s的正态分布的平均值。

import numpy as np

import statsmodels.formula.api as sm

import matplotlib.pyplot as plt

if __name__ == "__main__":

mu = 0

sigma = 1

samplenum = 10000

#设置随机数生成器种子,每次运行的随机数都是一样的。

np.random.seed(0)

samples = np.random.normal(mu,sigma,samplenum)

mu_sample = np.mean(samples)

#计算累加平均数

x = list(samples.cumsum(0))

n = [i for i in range(1,len(x)+1)]

cummean = [a/b for a,b in zip(x,n)]

马尔可夫链蒙特卡罗

定义

表示在t时间一些随机变量的值。马尔可夫链起始于

产生一系列样点

,接着一系列随机步骤。

马尔可夫链满足马尔可夫属性。马尔可夫属性是已知现在状态的条件下,将来所处的状态与过去状态无关,即“遗忘性”;基本上不管你如何达到某个状态x,x的转移概率不变:

从一个步骤到下一个步骤的转换是由转移核描述,它可以由状态i到状态j的转变的概率(或连续变量的概率密度)描述为

表示状态j在t时间(步骤)的链的概率,并且定义

为可能的状态的概率的向量。然后,给出

,我们利用Chapman-Kolmogorov方程计算

这个概率是我们在状态k乘以从k到i的转变的概率,在所有可能的状态k上求和。设P是概率转移矩阵——矩阵的第i,j元素是P(i→j),并且将上述等式重写为

我们可以轻松地迭代这个方程:

平稳分布

如果有一些矢量

满足

那么$\vec\pi^$是这个马尔可夫链的平稳分布。直观地,认为这个系统将设置的状态的最终特征集;运行足够长的时间,该系统会“遗忘”它的初始状态,则这个向量的第i个元素是这个系统将在状态i的概率。

如果这个过程是不可约的和非周期性的,马尔可夫链将会有一个平稳分布。

在数学上,

是特征值为1的左特征向量。

这里有一个快速的定义,使事情更具体(但请注意,这无关MCMC本身–这只是对马尔可夫链的观点!)假设我们有一个三态马尔可夫过程。设P为链的概率转移矩阵:

p = np.array([[0.5,0.25,0.25],[0.2, 0.1, 0.7],[0.25, 0.25, 0.5]])

print(p[1,1])

请注意,P行的共计为一:

入口P[i,j]给出了从状态i到状态j的概率(所以这就是上述的P(i→j))。

注意,与行不同,列不一定共计为1:

这个函数取一个状态向量x(其中x[i]是处于状态i的概率),并通过乘以转移矩阵P来迭代它,使系统前进n个步骤。

def iterate(x,p,n):

res = np.zeros((n+1,x.size))

res[0,] = x

for i in range(n):

res[i+1,] = x = np.dot(x,p)

return res从状态1中的系统开始(所以x是向量[ 1,0,0 ],指示存在处于状态1的100%概率,并且没有处于任何其他状态的机会),并且迭代10个步骤 :

n = 10

x = np.array([1,0,0])

y1 = iterate(np.array([0,1,0]),p,n)同样,对于其他两个可能的起始状态:

y2 = iterate(np.array([1,0,0]),p,n)

y3 = iterate(np.array([0,0,1]),p,n)这表明在平稳分布上的收敛性。

X=np.linspace(0,n+1,11)

plt.plot(X,y1,"-",X, y2, ":",X, y3, "-.")

plt.legend(loc="best",ncol=3,labels=["line11","line12","line13","line21","line22","line23","line31","line32","line33"])

plt.show()

这意味着不管起始分布如何,不管它在哪里开始,在大约10次或更多次迭代之后,链处于状态1的概率为32%。

我们可以用R的特征函数来提取系统的主导特征向量(这里的t()转置矩阵得到左特征向量)。

然后添加点到之前显示我们接近收敛的图中:

根据特征向量的定义,乘以特征向量的转移矩阵返回特征向量本身:

(严格地说,这应该是由V相乘的特征值,但这些矩阵的主特征值总是1)。

在这里运行的函数用一个状态(这一次,只是一个整数代表其中系统的状态1,2,3),如上相同的转移矩阵,和一些运行的步骤。每个步骤,查看可能转换到的地方,并选择1(这使用R的样本函数)。

这是100步左右的链:

绘制我们在每个状态随着时间的推移的时间分数。

运行这步再长一点(5000步)

存在稳定分布的充分(但不是必要的)条件是细致平衡,其为:

这意味着链是可逆的。这种情况意味着一个平稳分布存在的原因是

将状态j的细致平衡方程的两侧求和

左边的项等于

的第k个元素,右边的项可以作为因子

然后,因为

因为P是一个转移概率函数,由总概率定律决定,概率为1)所以右边是

,所以我们有

其适用于所有k,所以

马尔可夫链具有平稳分布,如果我们运行它们足够长的时间,我们可以看看链在哪里花费时间,并得到该平稳分布的合理估计。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。