今回の目的
今回は金融工学(というより確率過程)を勉強していて出てきたフィルトレーションという概念について、その感覚的・視覚的理解を得ることを目的とします。
なお著者はシュリーヴ著「ファイナンスのための確率解析 II」を読んで勉強しており、数学的定義などは本書より引用しています。
フィルトレーションの定義と例
定義
フィルトレーション$\mathcal{F}(t)$とは次のように定義される。
$\Omega$を空でない集合とする。$T$を正の定数とし、各$t\in[0, T]$に対して$\sigma$-加法族$\mathcal{F}(t)$があると仮定する。さらに、もし$s\leq t$ならば$\mathcal{F}(s)$に属するすべての集合は$\mathcal{F}(t)$にも属すると仮定する。このとき、$\sigma$-加法族の集まり$\mathcal{F}(t), 0\leq t\leq T$をフィルトレーションと呼ぶ。 |
---|
なんのこっちゃという感じです。嚙み砕いて言うと、各時刻について定義された$\Omega$の$\sigma$-加法族$\mathcal{F}(t)$で、時刻が進むとどんどん大きくなっていくもののことです。噛み砕いてもよくわかりません。
例
具体的に$\Omega$を定義して、フィルトレーションを作ってみたいと思います。$\Omega$として、$0\leq t \leq T$で定義されて$t=0$で$0$になる連続関数全体の集合を考えます:
\Omega = C_0[0, T] = \lbrace\ \omega\ |\ \omega: [0, T]\rightarrow \mathbb{R},\ \omega(0) = 0,\ \omega:連続 \rbrace
今、$\tau\in[0, T)$を一つ選び、$f\in C_0[0, \tau]$を一つ選びます。この$\tau, f$に対して$\Omega$の部分集合$A_{\tau, f}$を次のように定義します:
A_{\tau, f} = \lbrace\ \omega\ |\ \omega\in\Omega,\ \omega(t) = f(t)\ (0\leq t\leq\tau)\ \rbrace
つまり、$0\leq t\leq\tau$で共通の振る舞いをする元を全て取ってきた部分集合です。$t>\tau$での振る舞いに関する制限はありません。
この部分集合$A_{\tau, f}$は、$\Omega$の分割を与えます。すなわち、$f$に関して排反であり、$f$について和集合を取ると$\Omega$になります。数式で書けば
\displaylines{
\forall\ f_1, f_2 \in C_0[0, \tau]\ (f_1\neq f_2),\ A_{\tau, f_1}\ \cap\ A_{\tau, f_2} = \varnothing\\
\Omega = \bigcup_{f\in C_0[0, \tau]} A_{\tau, f}
}
を満たします。$0\leq t\leq \tau$の振る舞いで$\Omega$の元を分類したものが$A_{\tau, f}$だったので、ここは自明でいいと思います。
ここで、次のようにして$\sigma$-加法族を生成します。
\mathcal{F}(\tau) = \sigma(\lbrace\ A_{\tau, f}\ |\ f\in C_0[0, \tau]\rbrace)
なお、$\sigma(\cdot)$は与えられた集合族を含む最小の$\sigma$-加法族を生成する演算を表します。これを生成された$\sigma$-加法族と呼んだりするそうです(Wikipedia)。つまり、異なる$f$に関する$A_{\tau, f}$同士の和集合や補集合を取ってできる集合全体の集合、ということです。
このように作った$\mathcal{F}(\tau)$は$\tau$に関して増加する$\sigma$-加法族になります。$0\leq \tau_1 < \tau_2 \leq T$に対して、任意に$f_1\in C_0[0, \tau_1]$を取り、$A_{\tau_1, f_1} \in \mathcal{F}(\tau_1)$を考えます。この時、次のような$C_0[0, \tau_2]$の部分集合$I_{f_1}$を取ってきます。
I_{f_1}=\lbrace\ f\in C_0[0, \tau_2]\ |\ f(t)=f_1(t)\ (0\leq t\leq\tau_1)\rbrace \subset C_0[0, \tau_2]
この時、次の関係が成り立ちます。
A_{\tau_1, f_1} = \bigcup_{f\in I_{f_1}} A_{\tau_2, f}
言っていることは単純で、「$\Omega$の部分集合として$0\leq t\leq\tau_1$で$f_1$と同じ振る舞いをする要素を全て取ってくる」という操作を両辺それぞれ別の言い方で表現しているだけです。今、$A_{\tau_2, f}\in\mathcal{F}(\tau_2)$であるので、それらの和である右辺も$\sigma$-加法族の定義から$\mathcal{F}(\tau_2)$の要素になります。よって$A_{\tau_1, f_1}\in\mathcal{F}(\tau_2)$です。$f_1$は任意だったので、$\mathcal{F}(\tau_1)\subset\mathcal{F}(\tau_2)$が結論付けられます。従って、このようにして構築した$\sigma$-加法族$\mathcal{F}(\tau)$はフィルトレーションになります。
時刻$\tau$におけるフィルトレーション$\mathcal{F}(\tau)$は$0\leq t\leq\tau$での情報のみによって$\Omega$の元を分類したもので、それ以降の振る舞いが異なっていても$\mathcal{F}(\tau)$の中では同一視されます。ここから時間が進んで$t=\tau + dt$になると、$[\tau, \tau+dt]$での情報が追加されるので、$\mathcal{F}(\tau)$で同じ部分集合に属していた要素が、$\mathcal{F}(\tau+dt)$では分かたれて別々の部分集合に属するようになります。このようにして時刻が経つにつれて分類が細分化されていく様は、まさにフィルトレーションの特徴を表しています。
フィルトレーションの可視化
さて、このフィルトレーションの下でブラウン運動を生成します。シミュレーションの条件は以下の通りです。
- ブラウン運動$W(t)$は正規分布$\mathcal{N}(0, t)$に従う
- $0\leq t\leq T$でブラウン運動を生成
- $\tau\in[0, T]$を選び、$\mathcal{F}(\tau)$の下で同じ部分集合に含まれる信号を同色で表示
- $T=10, \tau=2, 5, 8$でそれぞれシミュレート
この下でのシミュレーション結果を以下に示します。
この図は、例えば赤色で示された信号は$0\leq t\leq \tau$で同じ波形$f_1(t)$を持ち、$\tau\leq t\leq T$ではランダム生成された波形を持ちます。この赤色で示された波形は全て、$\mathcal{F}(\tau)$に属する部分集合$A_{\tau, f_1}$の元です。同様に関数$f_2, f_3$が存在し、青色の信号は$A_{\tau, f_2}$, 緑色の信号は$A_{\tau, f_3}$に属します。$\tau$が増加していく毎に$A_{\tau, f}$が縮小していき、信号がより細分化されていることになります。
おまけ1 - マルチンゲール性
フィルトレーション$\mathcal{F}(t)$の下で、$s\leq t$として以下の性質を満たす確率過程$X(t)$をマルチンゲールと呼びます。
\mathbb{E}[X(t)|\mathcal{F}(s)] = X(s)
この左辺は条件付き期待値と呼び、$\mathcal{F}(s)$の下で$X(t)$の期待値を計算します。すなわち、時刻$s$から$t$の間の値が
(この辺りで条件付き期待値の理解が怪しくなってきたので後日追記予定)
おまけ2 - 使用コード
import numpy as np
import matplotlib.pyplot as plt
from math import sqrt, floor
dt = 0.01
T=10.0
seed=47
np.random.seed(seed)
def brown_array(tau):
W = [0]
t = [0]
for i in range(1, floor(tau / dt)):
dW = np.random.normal(0, sqrt(dt))
W.append(W[i-1] + dW)
t.append(t[i-1] + dt)
t = np.array(t)
W = np.array(W)
return t, W
def brown_plot(ax, tau, T, seed=seed, n=100, color='blue'):
np.random.seed(seed)
time_before_tau, W_before_tau = brown_array(T)
time_mask = time_before_tau < tau
time_before_tau = time_before_tau[time_mask]
W_before_tau = W_before_tau[time_mask]
ax.plot(time_before_tau, W_before_tau, color=color)
for i in range(n):
time_after_tau, W_after_tau = brown_array(T-tau)
time_after_tau = time_after_tau + tau
W_after_tau = W_after_tau + W_before_tau[-1]
ax.plot(time_after_tau, W_after_tau, color=color, alpha=0.1)
fig = plt.figure(figsize=(10, 6))
ax = fig.add_subplot(111)
tau = 8.0 # ここを変える
n = 100
brown_plot(ax, tau, T, seed=seed, color='blue')
brown_plot(ax, tau, T, seed=seed+1, color='red')
brown_plot(ax, tau, T, seed=seed+2, color='green')
ax.axvline(x=tau, linestyle='dashed', color='black', linewidth=0.5)
ax.set_ylabel(r'$W(t)$')
ax.set_xlabel(r'$t$')
ax.set_title(rf"$\tau=${tau}")
ax.set_ylim([-7.5, 7.5])
ax.set_xticks([0, tau, T])
ax.set_xticklabels(['0', rf'$\tau=${tau}', rf'$T=${T}'])
plt.show()