33. 马尔科夫链:基本概念#
除了 Anaconda 中的自带函数库之外,本讲还需要以下函数库,可以通过以下指令下载:
!pip install quantecon
Show output
Requirement already satisfied: quantecon in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (0.8.0)
Requirement already satisfied: numba>=0.49.0 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from quantecon) (0.60.0)
Requirement already satisfied: numpy>=1.17.0 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from quantecon) (1.26.4)
Requirement already satisfied: requests in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from quantecon) (2.32.3)
Requirement already satisfied: scipy>=1.5.0 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from quantecon) (1.13.1)
Requirement already satisfied: sympy in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from quantecon) (1.13.2)
Requirement already satisfied: llvmlite<0.44,>=0.43.0dev0 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from numba>=0.49.0->quantecon) (0.43.0)
Requirement already satisfied: charset-normalizer<4,>=2 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from requests->quantecon) (3.3.2)
Requirement already satisfied: idna<4,>=2.5 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from requests->quantecon) (3.7)
Requirement already satisfied: urllib3<3,>=1.21.1 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from requests->quantecon) (2.2.3)
Requirement already satisfied: certifi>=2017.4.17 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from requests->quantecon) (2024.8.30)
Requirement already satisfied: mpmath<1.4,>=1.1.0 in /home/runner/miniconda3/envs/quantecon/lib/python3.12/site-packages (from sympy->quantecon) (1.3.0)
33.1. 概述#
马尔科夫链提供了一种在过去对未来有影响的情况下进行建模的方法。
也就是说,观察当前情况的一些指标可以帮助我们预测未来的情况。
当在不同时间点对某事物的指标之间存在统计依赖时,这样的作法是可行的。
例如,
明年的通货膨胀可能与今年的通货膨胀有着相互关联的变化
下个月的失业率可能与本月的失业率有着相互关联的变化
马尔科夫链是经济学和金融学的一个重要工具。
马尔科夫链理论是美丽的,并为概率和动态变化相关的领域提供了许多见解。
在本讲中,我们将
回顾马尔科夫链理论中的一些关键思想,并
展示马尔科夫链在经济学中的应用。
让我们从一些通常的函数包导入开始:
import matplotlib.pyplot as plt
import quantecon as qe
import numpy as np
import networkx as nx
from matplotlib import cm
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.animation import FuncAnimation
from IPython.display import HTML
from matplotlib.patches import Polygon
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
33.2. 定义与示例#
在本节中,我们将提供一些定义和基本示例。
33.2.1. 随机矩阵#
概率质量函数是一个
例如,
随机矩阵(或马尔科夫矩阵)是一个
也就是说,
的每个元素都是非负的,且 的每一行的和为 1
如果
你将在一个练习中验证这一点。
33.2.2. 马尔科夫链#
现在我们可以引入马尔科夫链。
在严格定义马尔科夫链之前,我们先给出一些示例。
33.2.2.1. 示例 1#
根据美国失业数据,Hamilton [Hamilton, 2005] 估算了以下动态变化。

这里可以分为三个状态:
“ng” 表示正常增长(normal growth)
“mr” 表示轻度衰退(mild recession)
“sr” 表示严重衰退(severe recession)
箭头代表一个月内的转移概率。
例如,从轻度衰退到正常增长的箭头旁边有 0.145。
这告诉我们,根据过去的数据,从轻度衰退转移到正常增长的概率为 14.5%。
从正常增长回到正常增长的箭头告诉我们,从正常增长转移到正常增长(保持在同一状态)的概率为 97%。
请注意,这些转移概率其实是条件概率——从一个状态转移到另一个状态(或保持在同一状态)的概率是以当前状态为条件的。
为了便于数值处理,让我们用数字来表示状态。
具体来说,我们约定
状态 0 代表正常增长
状态 1 代表轻度衰退
状态 2 代表严重衰退
令
现在我们可以将“轻度衰退转移到正常增长的概率为 14.5%”的陈述写为
我们可以将所有这些条件概率写到一个矩阵中,如下所示:
注意,
现在我们有以下关系:
这对于任何
在此之中,
33.2.2.2. 示例 2#
考虑一个工人,在任何给定时间
假设在一个月内,
失业的工人以概率
找到工作。就业的工人以概率
失去工作并变成失业状态。
根据上述信息,我们可以将转移概率写成矩阵形式
例如,
假设我们可以估计
那么我们可以解决一系列问题,例如
失业的平均持续时间是多少?
从长期来看,工人失业的时间占总时间的多少?
在就业的条件下,工人在接下来的 12 个月内至少失业一次的概率是多少?
我们将在下面讨论其中一些应用。
33.2.2.3. 示例 3#
Imam 和 Temple [Imam and Temple, 2023] 将政治制度分类为三种类型:民主
每种制度都可以有两种可能的发展模式:崩溃
Imam 和 Temple [Imam and Temple, 2023] 估计了以下转移概率:
nodes = ['DG', 'DC', 'NG', 'NC', 'AG', 'AC']
P = [[0.86, 0.11, 0.03, 0.00, 0.00, 0.00],
[0.52, 0.33, 0.13, 0.02, 0.00, 0.00],
[0.12, 0.03, 0.70, 0.11, 0.03, 0.01],
[0.13, 0.02, 0.35, 0.36, 0.10, 0.04],
[0.00, 0.00, 0.09, 0.11, 0.55, 0.25],
[0.00, 0.00, 0.09, 0.15, 0.26, 0.50]]
下面是可视化图,颜色越深表示概率越高。
Show source
G = nx.MultiDiGraph()
for start_idx, node_start in enumerate(nodes):
for end_idx, node_end in enumerate(nodes):
value = P[start_idx][end_idx]
if value != 0:
G.add_edge(node_start,node_end, weight=value)
pos = nx.spring_layout(G, seed=10)
fig, ax = plt.subplots()
nx.draw_networkx_nodes(G, pos, node_size=600, edgecolors='black', node_color='white')
nx.draw_networkx_labels(G, pos)
arc_rad = 0.2
edges = nx.draw_networkx_edges(G, pos, ax=ax, connectionstyle=f'arc3, rad = {arc_rad}', edge_cmap=cm.Blues, width=2,
edge_color=[G[nodes[0]][nodes[1]][0]['weight'] for nodes in G.edges])
pc = mpl.collections.PatchCollection(edges, cmap=cm.Blues)
ax = plt.gca()
ax.set_axis_off()
plt.colorbar(pc, ax=ax)
plt.show()
查看数据后,我们发现民主政体的增长期通常比专制政体更长(这体现在专制政体中从增长到增长的转移概率较低)。
我们还可以发现,在民主政体中,从崩溃到增长的概率较高。
33.2.3. 定义马尔科夫链#
到目前为止,我们已经给出了马尔科夫链的示例,但还没有对其进行定义。
现在让我们进行定义。
首先,设
集合
一个分布
在
也就是,对于任何时间
这意味着一旦我们知道当前状态
因此,马尔科夫链的动态完全由条件概率的集合决定:
根据构造,
是从 到 在一个时间单位(一步)内的转移概率 是给定 时, 的条件分布
我们可以将
反过来,如果我们取一个随机矩阵
从
上的分布 中抽取对于每个
,从 中抽取
通过构造,所得的过程满足 (33.3)。
33.3. 模拟#
学习马尔科夫链的一个好方法是模拟它们。
让我们先自己独立试着模拟,然后再使用能够帮助我们的函数库进行模拟。
在接下来的练习中,我们将状态空间设为
(我们从
33.3.1. 编写我们自己的模拟代码#
要模拟一个马尔科夫链,我们需要
一个随机矩阵
和一个长度为
的概率质量函数 ,从中抽取 的初始实现。
然后按照如下方式构建马尔科夫链:
在时间
,从分布 中抽取 的一个实现。在每个后续时间
,从 中抽取一个新状态 的实现。
(也就是说,从
要实现这个模拟过程,我们需要一种方法从离散分布中生成抽取结果。
对于这个任务,我们将使用 QuantEcon.py 中的 random.draw
。
要使用 random.draw
,我们首先需要将概率质量函数转换为累积分布。
ψ_0 = (0.3, 0.7) # {0, 1} 上的概率分布
cdf = np.cumsum(ψ_0) # 转换为累积分布
qe.random.draw(cdf, 5) # 从 ψ 中生成 5 个独立抽取
array([0, 1, 0, 1, 1])
我们将编写一个函数,该函数接受以下三个参数:
随机矩阵
P
。初始分布
ψ_0
。正整数
ts_length
,表示函数应返回的时间序列的长度。
def mc_sample_path(P, ψ_0=None, ts_length=1_000):
# 设置
P = np.asarray(P)
X = np.empty(ts_length, dtype=int)
# 将 P 的每一行转换为累积分布函数(cdf)
P_dist = np.cumsum(P, axis=1) # 将行转换为 cdf
# 抽取初始状态,默认为 0
if ψ_0 is not None:
X_0 = qe.random.draw(np.cumsum(ψ_0))
else:
X_0 = 0
# 模拟
X[0] = X_0
for t in range(ts_length - 1):
X[t+1] = qe.random.draw(P_dist[X[t], :])
return X
让我们看看它是如何工作的,使用一个小的矩阵
P = [[0.4, 0.6],
[0.2, 0.8]]
以下是一个短的时间序列。
mc_sample_path(P, ψ_0=(1.0, 0.0), ts_length=10)
array([0, 0, 0, 1, 1, 1, 1, 1, 1, 1])
可以证明,从矩阵 P
中生成的长序列中,取值为 0 的样本占比将约为 0.25。
(我们将在稍后解释为什么。)
而且,这与
下面的代码演示了这一点
X = mc_sample_path(P, ψ_0=(0.1, 0.9), ts_length=1_000_000)
np.mean(X == 0)
0.249971
您可以尝试更改初始分布,以确认输出总是接近 0.25(对于上述矩阵 P
)。
33.3.2. 使用 QuantEcon 的例程#
QuantEcon.py 提供了一些处理马尔科夫链包括模拟的步骤。
以下是使用与前例相同的
mc = qe.MarkovChain(P)
X = mc.simulate(ts_length=1_000_000)
np.mean(X == 0)
0.249548
simulate
例程速度更快(因为它是 JIT 编译 的)。
%time mc_sample_path(P, ts_length=1_000_000) # 我们自制的代码版本
CPU times: user 1.17 s, sys: 0 ns, total: 1.17 s
Wall time: 1.17 s
array([0, 1, 0, ..., 1, 1, 0])
%time mc.simulate(ts_length=1_000_000) # qe 代码版本
CPU times: user 12.2 ms, sys: 2.06 ms, total: 14.2 ms
Wall time: 13.8 ms
array([1, 0, 0, ..., 1, 1, 1])
33.3.2.1. 添加状态值和初始条件#
如果需要,我们可以向 MarkovChain
提供表示状态的值的规范。
这些状态值可以是整数、浮点数,甚至是字符串。
以下代码说明了这一点
mc = qe.MarkovChain(P, state_values=('失业', '就业'))
mc.simulate(ts_length=4, init='就业') # 从就业初始状态开始
array(['就业', '就业', '失业', '失业'], dtype='<U2')
mc.simulate(ts_length=4, init='失业') # 从失业初始状态开始
array(['失业', '就业', '失业', '失业'], dtype='<U2')
mc.simulate(ts_length=4) # 从随机选择的初始状态开始
array(['就业', '就业', '就业', '就业'], dtype='<U2')
如果我们希望看到状态值对应的索引而不是状态值本身作为输出,我们可以使用
mc.simulate_indices(ts_length=4)
array([1, 1, 0, 0])
33.4. 随时间分布#
我们了解到
是一个具有随机矩阵 的马尔科夫链 的分布已知为
那么,
为了回答这个问题,令
我们的第一个目标是找到给定
首先,选择任意
为了得到明天(
这导致了
(我们正在使用全概率公式。)
将这一表达式重新写为边缘概率和条件概率的形式:
有
如果我们将
因此,我们通过右乘
通过右乘
因此,迭代 (33.4),表达式
作为一个特例,我们看到,如果
这非常重要,所以我们重复一下
一般规则是通过右乘
因此,以下推断也是有效的。
33.4.1. 多步转移概率#
我们已知从
实际上,从
要理解为什么是这样,请再次考虑 (33.6),但现在设
此时,
将其代入 (33.6),我们看到,条件
特别地,
33.4.2. 示例:衰退概率#
回顾我们之前讨论的关于衰退和增长的随机矩阵
假设当前状态未知——也许统计数据只能在当前月份结束时获得。
我们假设,在时间
那么,6 个月后处于衰退(无论是轻度还是严重衰退)的概率为
33.4.3. 示例 2:横截面分布#
我们研究的分布可以视为
概率,或
横截面频率,即根据大数法则我们预期的大样本中的结果。
为了解释这一点,请回顾我们之前讨论的关于单个工人就业/失业动态的模型 上面讨论过的。
现在考虑一个大的工人群体,每个工人的一生经历都符合指定的动态,每个工人的结果都是与其他工人独立的过程的实现。
令
横截面分布记录了某一时刻
例如,
是时间 的失业率。
10 个周期之后,横截面分布会是什么样子?
答案是
这是因为每个工人的状态都根据
但当样本很大时,结果和概率大致相等(通过应用大数法则)。
因此,对于一个非常大的(趋向于无限)群体,
这正是横截面分布。
33.5. 平稳分布#
如 (33.4) 所示,我们可以通过右乘
一些分布在此更新过程中是不变的——例如,
P = np.array([[0.4, 0.6],
[0.2, 0.8]])
ψ = (0.25, 0.75)
ψ @ P
array([0.25, 0.75])
注意,ψ @ P
与 ψ
相同(可以验证
这样的分布被称为平稳或不变分布。
严格的表述如下,如果分布
注意,通过右乘
继续以同样的方式推导得到
这告诉我们一个重要的事实:如果分布
以下定理在 [Sargent and Stachurski, 2023] 的第 4 章及其他许多来源中得到了证明。
Theorem 33.1
每个随机矩阵
请注意,对于给定的随机矩阵
例如,如果
是单位矩阵,那么 上的所有分布都是平稳的。
为了获得唯一性,我们需要马尔科夫链“混合”,以便状态不会卡在状态空间的某一部分。
这为以下定理提供了一些直觉。
Theorem 33.2
如果
我们将在 下一讲 中引入不可约性时回到这一点。
33.5.1. 示例#
回顾我们之前讨论的关于特定工人的就业/失业动态的模型 在上面讨论过的。
如果
设
使用
从某种意义上说,这是失业的稳态概率。
不出所料,当
33.5.2. 计算平稳分布#
QuantEcon.py 实现了计算平稳分布的稳定算法。
这里是一个示例
P = [[0.4, 0.6],
[0.2, 0.8]]
mc = qe.MarkovChain(P)
mc.stationary_distributions # 显示所有平稳分布
array([[0.25, 0.75]])
33.5.3. 渐进平稳性#
考虑一个处处为正的随机矩阵,具有唯一的平稳分布
有时,无论初始分布
例如,我们有以下结果
Theorem 33.3
如果存在一个整数
其中
这种情况通常称为渐进平稳性或全局稳定性。
该定理的证明可以在 [Sargent and Stachurski, 2023] 的第4章或许多其他来源中找到。
33.5.3.1. 示例:汉密尔顿链#
汉密尔顿链满足定理的条件,因为
P = np.array([[0.971, 0.029, 0.000],
[0.145, 0.778, 0.077],
[0.000, 0.508, 0.492]])
P @ P
array([[0.947046, 0.050721, 0.002233],
[0.253605, 0.648605, 0.09779 ],
[0.07366 , 0.64516 , 0.28118 ]])
我们选择初始分布
首先,我们编写一个函数,用于迭代分布序列,持续 ts_length
个时间段
def iterate_ψ(ψ_0, P, ts_length):
n = len(P)
ψ_t = np.empty((ts_length, n))
ψ_t[0 ]= ψ_0
for t in range(1, ts_length):
ψ_t[t] = ψ_t[t-1] @ P
return ψ_t
现在我们绘制序列
Show source
ψ_1 = (0.0, 0.0, 1.0)
ψ_2 = (1.0, 0.0, 0.0)
ψ_3 = (0.0, 1.0, 0.0) # 三个初始条件
colors = ['blue','red', 'green'] # 不同颜色表示不同的初始点
# 定义单位单纯形的顶点
v = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 0]])
# 定义单位单纯形的面
faces = [
[v[0], v[1], v[2]],
[v[0], v[1], v[3]],
[v[0], v[2], v[3]],
[v[1], v[2], v[3]]
]
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
def update(n):
ax.clear()
ax.set_xlim([0, 1])
ax.set_ylim([0, 1])
ax.set_zlim([0, 1])
ax.view_init(45, 45)
simplex = Poly3DCollection(faces, alpha=0.03)
ax.add_collection3d(simplex)
for idx, ψ_0 in enumerate([ψ_1, ψ_2, ψ_3]):
ψ_t = iterate_ψ(ψ_0, P, n+1)
for i, point in enumerate(ψ_t):
ax.scatter(point[0], point[1], point[2], color=colors[idx], s=60, alpha=(i+1)/len(ψ_t))
mc = qe.MarkovChain(P)
ψ_star = mc.stationary_distributions[0]
ax.scatter(ψ_star[0], ψ_star[1], ψ_star[2], c='yellow', s=60)
return fig,
anim = FuncAnimation(fig, update, frames=range(20), blit=False, repeat=False)
plt.close()
HTML(anim.to_jshtml())
在这里
是 之前讨论的 衰退和增长的随机矩阵。红色、蓝色和绿色的点是初始边缘概率分布
,它们分别表示为 中的向量。各种颜色的透明点是边际分布
对于 , 。黄色点是
。
你可以尝试不同的初始条件来进行实验。
33.5.3.2. 示例:收敛失败#
考虑一个具有以下随机矩阵的周期链
该矩阵不满足 strict_stationary 的条件,因为很容易检验到:
当
为奇数时,当
为偶数时, ,即单位矩阵。
因此,没有
此外,我们可以看到,全局稳定性并不成立。
例如,如果我们从
我们可以在更高维度中看到类似的现象。
下图展示了具有三个状态的周期性马尔科夫链。
Show source
ψ_1 = (0.0, 0.0, 1.0)
ψ_2 = (0.5, 0.5, 0.0)
ψ_3 = (0.25, 0.25, 0.5)
ψ_4 = (1/3, 1/3, 1/3)
P = np.array([[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0],
[1.0, 0.0, 0.0]])
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
colors = ['red','yellow', 'green', 'blue'] # 不同颜色表示不同的初始点
# 定义单位单纯形的顶点
v = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 0]])
# 定义单位单纯形的面
faces = [
[v[0], v[1], v[2]],
[v[0], v[1], v[3]],
[v[0], v[2], v[3]],
[v[1], v[2], v[3]]
]
def update(n):
ax.clear()
ax.set_xlim([0, 1])
ax.set_ylim([0, 1])
ax.set_zlim([0, 1])
ax.view_init(45, 45)
# 绘制 3D 单纯形作为平面
simplex = Poly3DCollection(faces,alpha=0.05)
ax.add_collection3d(simplex)
for idx, ψ_0 in enumerate([ψ_1, ψ_2, ψ_3, ψ_4]):
ψ_t = iterate_ψ(ψ_0, P, n+1)
point = ψ_t[-1]
ax.scatter(point[0], point[1], point[2], color=colors[idx], s=60)
points = np.array(ψ_t)
ax.plot(points[:, 0], points[:, 1], points[:, 2], color=colors[idx],linewidth=0.75)
return fig,
anim = FuncAnimation(fig, update, frames=range(20), blit=False, repeat=False)
plt.close()
HTML(anim.to_jshtml())
该动画展示了一个不可约但具有周期性的随机矩阵的行为。
红色、黄色和绿色的点表示不同的初始概率分布。
蓝色点表示唯一的平稳分布。
与汉密尔顿的马尔科夫链不同,这些初始分布不会收敛到唯一的平稳分布。
相反,它们周期性地在概率单纯形上循环,说明了此时渐进稳定性失败的。
33.6. 计算期望#
我们有时需要计算形式为
以及条件期望,例如
其中
是由 随机矩阵 生成的马尔科夫链。 是给定的函数,我们在矩阵代数的意义上将其视为列向量
计算无条件期望 (33.7) 非常简单。
我们只需对
这里
由于
对于条件期望 (33.8),我们需要对
我们已经知道这是
33.6.1. 几何和的期望#
有时我们需要计算几何和的数学期望,例如
根据前面的讨论,这是
根据 Neumann 级数引理,该和可以使用以下公式计算
向量
Exercise 33.1
Imam 和 Temple [Imam and Temple, 2023] 使用了一个三状态转移矩阵来描述政权的三种状态:增长、停滞和崩溃
其中从上到下的行分别对应增长、停滞和崩溃。
在本练习中,
可视化转移矩阵,并证明该过程是渐进平稳的
使用模拟计算平稳分布
可视化
的动态过程,其中 ,并将收敛路径与之前的转移矩阵进行比较
将您的解答与论文进行比较。
Solution to Exercise 33.1
解答 1:

由于矩阵处处为正,因此存在唯一的平稳分布
解答 2:
一种简单的方法是计算转移矩阵的幂,如我们之前所示
P = np.array([[0.68, 0.12, 0.20],
[0.50, 0.24, 0.26],
[0.36, 0.18, 0.46]])
P_power = np.linalg.matrix_power(P, 20)
P_power
array([[0.56145769, 0.15565164, 0.28289067],
[0.56145769, 0.15565164, 0.28289067],
[0.56145769, 0.15565164, 0.28289067]])
注意,转移矩阵的行收敛到平稳分布。
ψ_star_p = P_power[0]
ψ_star_p
array([0.56145769, 0.15565164, 0.28289067])
mc = qe.MarkovChain(P)
ψ_star = mc.stationary_distributions[0]
ψ_star
array([0.56145769, 0.15565164, 0.28289067])
Exercise 33.2
我们之前 讨论过 的 Imam & Temple [Imam and Temple, 2023] 估计的六状态转移矩阵。
nodes = ['DG', 'DC', 'NG', 'NC', 'AG', 'AC']
P = [[0.86, 0.11, 0.03, 0.00, 0.00, 0.00],
[0.52, 0.33, 0.13, 0.02, 0.00, 0.00],
[0.12, 0.03, 0.70, 0.11, 0.03, 0.01],
[0.13, 0.02, 0.35, 0.36, 0.10, 0.04],
[0.00, 0.00, 0.09, 0.11, 0.55, 0.25],
[0.00, 0.00, 0.09, 0.15, 0.26, 0.50]]
在本练习中,
不使用模拟,证明该过程是渐进平稳的
模拟并可视化从各状态均匀分布开始的动态(每个状态的概率为 1/6)
将初始分布更改为 P(DG) = 1,其他所有状态的概率为 0
Solution to Exercise 33.2
解答 1:
虽然
P = np.array([[0.86, 0.11, 0.03, 0.00, 0.00, 0.00],
[0.52, 0.33, 0.13, 0.02, 0.00, 0.00],
[0.12, 0.03, 0.70, 0.11, 0.03, 0.01],
[0.13, 0.02, 0.35, 0.36, 0.10, 0.04],
[0.00, 0.00, 0.09, 0.11, 0.55, 0.25],
[0.00, 0.00, 0.09, 0.15, 0.26, 0.50]])
np.linalg.matrix_power(P,3)
array([[0.764927, 0.133481, 0.085949, 0.011481, 0.002956, 0.001206],
[0.658861, 0.131559, 0.161367, 0.031703, 0.011296, 0.005214],
[0.291394, 0.057788, 0.439702, 0.113408, 0.062707, 0.035001],
[0.272459, 0.051361, 0.365075, 0.132207, 0.108152, 0.070746],
[0.064129, 0.012533, 0.232875, 0.154385, 0.299243, 0.236835],
[0.072865, 0.014081, 0.244139, 0.160905, 0.265846, 0.242164]])
因此它满足要求。
解答 2:
无论初始分布如何,我们发现分布
ts_length = 30
num_distributions = 20
nodes = ['DG', 'DC', 'NG', 'NC', 'AG', 'AC']
# 获取转移矩阵的参数
n = len(P)
mc = qe.MarkovChain(P)
ψ_star = mc.stationary_distributions[0]
ψ_0 = np.array([[1/6 for i in range(6)],
[0 if i != 0 else 1 for i in range(6)]])
## 绘制图像
fig, axes = plt.subplots(ncols=2)
plt.subplots_adjust(wspace=0.35)
for idx in range(2):
ψ_t = iterate_ψ(ψ_0[idx], P, ts_length)
for i in range(n):
axes[idx].plot(ψ_t[:, i] - ψ_star[i], alpha=0.5, label=fr'$\psi_t({i+1})$')
axes[idx].set_ylim([-0.3, 0.3])
axes[idx].set_xlabel('t')
axes[idx].set_ylabel(fr'$\psi_t$')
axes[idx].legend()
axes[idx].axhline(0, linestyle='dashed', lw=1, color = 'black')
plt.show()
Exercise 33.3
证明以下命题:如果
Solution to Exercise 33.3
假设
我们将证明
(我们正在进行归纳证明——假设在
要看到这一点,注意到,由于
此外,如果
因此
证明完毕。