案例:数值模拟-随机漫步
数值模拟
- 用计算机模拟自然现象,达到研究现实问题的目的
随机漫步(随机游走,Random Walk):
布朗运动的数学表达
- 广泛用于数学/物理/互联网/金融等行业扩散现象的数值模拟
- 一滴墨汁掉进水里,花粉的布朗运动/金融市场的价格走势/搜索引擎算法
描述:
- 从起点开始,随机移动一步
- 以移动后的点做起点,重复以上过程
使用随机漫步模拟股票历史价格走势
生成不同维度的随机漫步数据,可视化
import numpy as np
import matplotlib.pyplot as plt
stock = np.random.randint(0, 2, 100000)
stock[:100]
array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1,
1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0,
1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0,
0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0,
1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1])
可视化
折线图,x时间轴自增,不需要设置
# 不符合现实
# plt.plot(stock)
plt.plot(stock[:100])
[<matplotlib.lines.Line2D at 0x7f4eb38>]
# 累加
stockSum = np.cumsum(stock)
stockSum[:100]
array([ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 5, 5, 5,
6, 7, 8, 9, 10, 11, 11, 11, 11, 12, 13, 14, 15, 15, 15, 16, 17,
18, 18, 18, 19, 20, 20, 20, 21, 22, 22, 23, 24, 24, 24, 24, 24, 25,
25, 26, 27, 28, 28, 28, 28, 29, 30, 30, 31, 32, 32, 33, 33, 33, 33,
34, 34, 34, 34, 34, 34, 35, 36, 36, 37, 37, 38, 39, 40, 40, 41, 41,
41, 42, 42, 43, 43, 44, 44, 44, 45, 45, 45, 46, 47, 48, 49],
dtype=int32)
# 不符合现实
plt.plot(stockSum[:100])
[<matplotlib.lines.Line2D at 0x811cbe0>]
随机漫步的步长为1
# 将数据从0,1转为-1,1,
stock2 = np.where(stock == 0, -1, 1)
stock2[:100]
array([-1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1,
1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1,
1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1,
-1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1,
1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1,
-1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1])
随机步长的起始值是上一次运动的终端值
# 累加
stockSum2 = np.cumsum(stock2)
stockSum2[:100]
array([-1, -2, -3, -4, -3, -4, -5, -6, -7, -8, -7, -6, -7, -6, -5, -6, -7,
-6, -5, -4, -3, -2, -1, -2, -3, -4, -3, -2, -1, 0, -1, -2, -1, 0,
1, 0, -1, 0, 1, 0, -1, 0, 1, 0, 1, 2, 1, 0, -1, -2, -1,
-2, -1, 0, 1, 0, -1, -2, -1, 0, -1, 0, 1, 0, 1, 0, -1, -2,
-1, -2, -3, -4, -5, -6, -5, -4, -5, -4, -5, -4, -3, -2, -3, -2, -3,
-4, -3, -4, -3, -4, -3, -4, -5, -4, -5, -6, -5, -4, -3, -2],
dtype=int32)
plt.figure(figsize=(18, 12))
plt.plot(stockSum2)
[<matplotlib.lines.Line2D at 0x817ec88>]
二维世界的随机漫步
1:生成随机数
x = np.random.randint(0, 2, 100000)
y = np.random.randint(0, 2, 100000)
x[:100]
array([0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1,
0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0,
0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1])
2: 修改步长,0转为-1
x2 = np.where(x == 1, 1, -1)
y2 = np.where(y == 1, 1, -1)
x2[:100]
array([-1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1,
1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1,
1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1,
1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1,
1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1])
3:本次移动起始点是上次移动终点,累加
x3 = np.cumsum(x2)
y3 = np.cumsum(y2)
x3[:100]
array([ -1, -2, -3, -2, -1, -2, -1, 0, 1, 0, -1, -2, -3,
-4, -5, -6, -7, -8, -9, -10, -11, -10, -11, -12, -13, -12,
-11, -10, -9, -10, -9, -10, -9, -10, -9, -10, -9, -10, -11,
-10, -11, -12, -13, -12, -13, -14, -13, -14, -15, -16, -17, -16,
-15, -16, -17, -18, -17, -16, -15, -16, -15, -16, -15, -16, -17,
-18, -19, -18, -17, -18, -17, -18, -19, -18, -19, -18, -19, -20,
-21, -20, -21, -22, -21, -22, -21, -20, -21, -22, -23, -24, -25,
-26, -27, -28, -29, -28, -29, -30, -29, -28], dtype=int32)
4:可视化
# %matplotlib notebook
plt.figure(figsize=(18, 18), dpi=300)
plt.plot(x3, y3)
[<matplotlib.lines.Line2D at 0x84fdc18>]
随机漫步路径动态可视化
x3[:100]
x3[3]
x3[3-1]
-3
# 随机漫步动画,每帧走一步
plt.plot(
x3[3:5],
y3[3:5],
)
[<matplotlib.lines.Line2D at 0x887fe48>]
%matplotlib notebook
from matplotlib.animation import FuncAnimation # 载入动画子库
fig, ax = plt.subplots()
# 动画每帧调用的函数
def update(i):
plt.title(i) # frame的值,随调用遍历
plt.plot(
x3[i-2:i],
y3[i-2:i],
)
# 动画方法
ani = FuncAnimation(
fig, # 动画应用的图像
update, # 动画每帧都要调用的函数
interval = 10, # 动画帧间隔,毫秒
frames = 100, # 动画帧数,对GIF有效,值调用函数内的i可以获取。可自定义值如range(50,100)
)
ani.save('line.gif', dpi=72, writer='imagemagick') # 动画帧数如果过多,执行时间很长
<IPython.core.display.Javascript object>
[<mpl_toolkits.mplot3d.art3d.Line3D at 0xa4adda0>]
随机漫步三维可视化
def d3(n):
x = np.random.randint(0, 2, n)
x2 = np.where(x == 1, 1, -1)
return np.cumsum(x2)
d3(100)
array([ 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 1, 2, 1,
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 1, 0,
1, 2, 1, 0, 1, 0, -1, -2, -3, -2, -1, 0, -1,
0, -1, 0, 1, 0, -1, 0, -1, -2, -3, -2, -1, -2,
-3, -4, -3, -4, -3, -4, -5, -6, -5, -4, -5, -6, -7,
-8, -9, -8, -7, -6, -7, -8, -7, -8, -7, -6, -5, -6,
-7, -8, -7, -6, -5, -6, -7, -8, -7, -6, -5, -6, -7,
-6, -7, -8, -9, -8, -9, -10, -9, -10], dtype=int32)
from mpl_toolkits.mplot3d import Axes3D # 载入三维子库
fig = plt.figure()
ax = Axes3D(fig)
ax.plot(
d3(5000),
d3(5000),
d3(5000),
)
<IPython.core.display.Javascript object>