马尔可夫链平稳分布的Python代码解释



我得到了这个代码:

import numpy as np
from scipy.linalg import eig 
transition_mat = np.matrix([
    [.95, .05, 0., 0.],
    [0., 0.9, 0.09, 0.01],
    [0., 0.05, 0.9, 0.05],
    [0.8, 0., 0.05, 0.15]])
S, U = eig(transition_mat.T)
stationary = np.array(U[:, np.where(np.abs(S - 1.) < 1e-8)[0][0]].flat)
stationary = stationary / np.sum(stationary)
>>> print stationary
[ 0.34782609  0.32608696  0.30434783  0.02173913]

但我听不懂这句话:

stationary = np.array(U[:, np.where(np.abs(S - 1.) < 1e-8)[0][0]].flat)

有人能解释一下U[:, np.where(np.abs(S - 1.) < 1e-8)[0][0]].flat吗?

我知道例程返回S:特征值,U:特征向量。我需要找到对应于特征值1的特征向量。我写了下面的代码:

for i in range(len(S)):
    if S[i] == 1.0:
        j = i
 matrix = np.array(U[:, j].flat)

我正在获得输出:

:  [ 0.6144763   0.57607153  0.53766676  0.03840477]

但是它不给出相同的输出。为什么?

如何找到平稳分布

好的,我来这篇文章是想看看是否有一个内置的方法来找到平稳分布。看起来没有。所以,对于任何来自谷歌的人来说,这就是我在这种情况下如何找到平稳分布:

import numpy as np
#note: the matrix is row stochastic.
#A markov chain transition will correspond to left multiplying by a row vector.
Q = np.array([
    [.95, .05, 0., 0.],
    [0., 0.9, 0.09, 0.01],
    [0., 0.05, 0.9, 0.05],
    [0.8, 0., 0.05, 0.15]])
#We have to transpose so that Markov transitions correspond to right multiplying by a column vector.  np.linalg.eig finds right eigenvectors.
evals, evecs = np.linalg.eig(Q.T)
evec1 = evecs[:,np.isclose(evals, 1)]
#Since np.isclose will return an array, we've indexed with an array
#so we still have our 2nd axis.  Get rid of it, since it's only size 1.
evec1 = evec1[:,0]
stationary = evec1 / evec1.sum()
#eigs finds complex eigenvalues and eigenvectors, so you'll want the real part.
stationary = stationary.real

那句奇怪的台词在干什么

让我们把这条线分成几个部分:

#Find the eigenvalues that are really close to 1.
eval_close_to_1 = np.abs(S-1.) < 1e-8
#Find the indices of the eigenvalues that are close to 1.
indices = np.where(eval_close_to_1)
#np.where acts weirdly.  In this case it returns a 1-tuple with an array of size 1 in it.
the_array = indices[0]
index = the_array[0]
#Now we have the index of the eigenvector with eigenvalue 1.
stationary = U[:, index]
#For some really weird reason, the person that wrote the code
#also does this step, which is completely redundant.
#It just flattens the array, but the array is already 1-d.
stationary = np.array(stationary.flat)

如果你把所有这些代码压缩成一行,你就会得到stationary = np.array(U[:, np.where(np.abs(S-1.)<1e-8)[0][0]].flat)

如果你去掉多余的东西,你会得到stationary = U[:, np.where(np.abs(S - 1.) < 1e-8)[0][0]]

为什么你的代码给出了一个不同的平稳向量

正如@Forzaa所指出的,你的向量不能代表概率向量,因为它不等于1。如果你把它除以它的和,你就会得到原始代码片段的向量。

只需添加这一行:

stationary = matrix/matrix.sum()

然后,您的固定分布将匹配。

stationary = np.array(U[:,np.where(np.abs(S-1.) < 1e-8)[0][0]].flat)

这段代码在U中搜索相应特征值-1小于1e-8

的元素

实际上,只需要做一个简单的while迭代。我将使用随机P作为的示例

def get_stationary(n):
    row = n
    pi = np.full((1, row), 1 / row)
    T = np.array([[1/4,1/2,1/4],
                  [1/3,0,2/3],
                  [1/2,0,1/2]])
    while True:
        new_pi = np.dot(pi, T)
        if np.allclose(pi, new_pi):
            return pi 
            break
        pi = new_pi
print(get_stationary(3))

相关内容

  • 没有找到相关文章

最新更新