布朗运动过程、复合泊松过程及马尔科夫链的离散模拟
- 前言
- 一:布朗运动模拟
- 二:泊松过程模拟
- 三:复合泊松过程与补偿泊松过程
- 四:离散马尔科夫链模拟
- 五:总结
前言
本篇文章主要聊一聊常见的随机过程的模拟(暂不涉及机器学习数据挖掘等),随机过程的相关理论还是非常深奥的,比如带跳的多维伊藤公式,鞅表示定理,Mallivian微积分等等,这篇文章将暂只涉及浅显知识点的概括,重点是模拟这些常见的过程,望对有兴趣的朋友提供些帮助,望志同道合的朋友在一起多多交流。
虽曰如云,匪我思存,写作不易,走过路过的朋友们,别忘了点赞收藏加关注一下哈,谢谢!
一:布朗运动模拟
- 概括
假设 ,其中分别是正态分布的均值和标准差,当 时为标准正态分布。令,则标准正态下有 。 - 代码模拟
def bm(days):
dt = 1 / days
rand_nums = np.random.normal(0, 1, days)
shock = rand_nums * np.power(dt,0.5)
W = np.cumsum(shock)
W = list(W)
W.insert(0,0)
return W
days = 365
fig = plt.figure(figsize=(15,8))
plt.plot(bm(days),label='轨迹1')
plt.plot(bm(days),label='轨迹2')
plt.plot(bm(days),label='轨迹3')
plt.legend(fontsize=18)
plt.tick_params(labelsize=15)
plt.show()
**
图1
二:泊松过程模拟
- 概括
我们在 时,令泊松事件计数值 ,定义指数分布随机数 ,其中 为泊松强度是一常数,可以理解为单位时间内发生的次数,很明显强度越大,我们到达指定发生的次数的时间就越短, 为均匀分布随机数(下同)。
我们划分 ,直到时间为 - 代码模拟
def pm(days,lamd):
rand_nums = np.random.uniform(0,1,days)
N = np.ones((1,days))
E = - np.log(rand_nums) / lamd
P = np.cumsum(N)
T = np.cumsum(E)
P = list(P)
T = list(T)
P.insert(0,0)
T.insert(0,0)
return P,T
fig = plt.figure(figsize=(15,8))
days = 60
res1 = pm(days,1)
res2 = pm(days,3)
res3 = pm(days,5)
plt.step(res1[1], res1[0], lw=2, label='强度为1')
plt.step(res2[1], res2[0], lw=2, label='强度为3')
plt.step(res3[1], res3[0], lw=2, label='强度为5')
plt.ylabel('计数次数',fontsize=15)
plt.xlabel('时间',fontsize=15)
plt.legend(fontsize=18)
plt.tick_params(labelsize=15)
plt.show()
图2
三:复合泊松过程与补偿泊松过程
理解了一般泊松过程后,复合和补偿是相当容易的两个拓展过程。
- 复合泊松过程
泊松事件计数值依然为 ,强度为 ,再令 为独立同分布随机变量,那么我们有
- 补偿泊松过程
我们记符号 为补偿泊松过程,则有 。 - 模拟上述两个过程
基于模拟考虑,我们简单令 即可,相应代码在上述泊松过程中进行简单修改即可(参数days依旧为60),我们不再重复编写,直接作出模拟图如下:
图3
图4
对于图4,我们从一般泊松过程期望出发( ,这里不再深入展开),那么对于补偿泊松过程,理论上在整个过程中,其值是在0附近上下扰动。
四:离散马尔科夫链模拟
- 概括
设离散马氏链 ,转移速率矩阵 为马氏链在 时的状态值,
为离散步长大小,那么我们定义转移概率矩阵如下: 当 时,有 , 当 时,有
, 这里
并且当 时有
,很明显由泰勒定理知,当 时,转移概率矩阵也可以定义为 当
时,, 当 时,
最后定义马氏链如下:
- 令 为初始状态,同时生成服从$ [0,1]$ 之间的均匀分布随机数 ,定义下个状态值如下 当
时,有
, 当 - 通常我们令 ,接着再生成一个服从之间的均匀分布随机数 来计算 , 当
时,有 , 当 时,有 - 代码模拟
def markov_m(days,delta):
original_value = 1## 设置初始状态
r = np.array([[-1, 0.1, 0.9], [0.05, -2, 1.95], [2, 3, -5]]) ###根据定义随意给的转移速率矩阵
p = r * delta
for i in range(r.shape[1]):
p[i, i] = 1 + p[i, i]
print(p)
U = np.random.uniform(0,1,days)
q = np.zeros((1,days))
# P = np.exp(delta * r) - 1
# for i in range(r.shape[1]):
# P[i, i] = 1 + P[i, i]
# print(P)###delta越小,P跟p越接近
for i in range(days):
u = U[i]
v_temp = original_value
q[:,i] = v_temp
original_value = 1
s = 0
while original_value <= p.shape[1] and u > s:
s = s + p[v_temp - 1, original_value - 1]###概率值叠加
original_value = original_value + 1###矩阵列索引变大
original_value = original_value - 1##由于开始original_value =1,所以要减1
return q.tolist()[0]
fig = plt.figure(figsize=(18,8))
days = 1000
x = [i for i in range(days)]
plt.tick_params(labelsize=15)
plt.subplot(1,3,1)
plt.ylim([0.5,3.5])
plt.ylabel('状态值',fontsize=15)
plt.step(x,markov_m(days,0.1),label='delta=0.1')
plt.legend(fontsize=15)
plt.subplot(1,3,2)
plt.ylim([0.5,3.5])
plt.ylabel('状态值',fontsize=15)
plt.step(x,markov_m(days,0.01),label='delta=0.01')
plt.legend(fontsize=15)
plt.subplot(1,3,3)
plt.ylim([0.5,3.5])
plt.ylabel('状态值',fontsize=15)
plt.step(x,markov_m(days,0.001),label='delta=0.001')
plt.legend(fontsize=15)
plt.ylim([0.5,3.5])
plt.show()
图5
从图5我们发现随着 ,由于转移速率矩阵到转移概率矩阵公式,我们知道 越小,转移概率矩阵的对角值越大,越接近1,再由马氏链定义可知,状态之间的切换概率越小。