ブラウン運動(ウィーナー過程)の理論を解説

1827年、植物学者ロバート・ブラウンは花粉から出た微粒子が水中で不規則に動くことを顕微鏡で観察しました。この不規則な運動は後に ブラウン運動 と呼ばれるようになります。1905年、アルベルト・アインシュタインは分子の熱運動による衝突がこの不規則運動の原因であることを理論的に示し、分子の存在を間接的に証明しました。

数学的には、ノーバート・ウィーナーが1923年にブラウン運動の厳密な構成を行い、そのため ウィーナー過程(Wiener process) とも呼ばれます。ブラウン運動は確率解析の基盤であり、確率微分方程式、金融工学(ブラック=ショールズ・モデル)、物理学(拡散過程)など、現代の応用数学の至る所に現れます。

本記事の内容

  • ブラウン運動の歴史的背景
  • 公理的定義(4条件)
  • ランダムウォークからの構成(Donskerの不変原理)
  • ブラウン運動の性質(連続だが至る所微分不可能、2次変分、マルコフ性、マルチンゲール性)
  • 幾何ブラウン運動
  • ブラウン橋
  • Pythonでのシミュレーション

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

ブラウン運動の公理的定義

4条件による定義

定義(標準ブラウン運動): 確率過程 $\{W(t)\}_{t \geq 0}$ が 標準ブラウン運動(standard Brownian motion) であるとは、以下の4つの条件を満たすことをいいます。

(B1) 初期条件: $W(0) = 0$ a.s.(概ね確実に)

(B2) 独立増分: $0 \leq t_1 < t_2 < \cdots < t_n$ に対して、増分

$$ W(t_2) – W(t_1), \quad W(t_3) – W(t_2), \quad \dots, \quad W(t_n) – W(t_{n-1}) $$

は互いに独立である。

(B3) 正規増分: 任意の $0 \leq s < t$ に対して、

$$ W(t) – W(s) \sim N(0, t – s) $$

つまり、増分は平均0、分散 $t – s$ の正規分布に従う。

(B4) 連続パス: サンプルパス $t \mapsto W(t, \omega)$ は確率1で連続である。

定義から導かれる基本性質

性質1: 平均と分散

条件(B1)と(B3)より、

$$ E[W(t)] = E[W(t) – W(0)] = 0 $$

$$ \text{Var}(W(t)) = \text{Var}(W(t) – W(0)) = t $$

分散が時間に比例して増大するのは、不確実性が時間とともに蓄積していくことを意味します。

性質2: 共分散

$s \leq t$ のとき、

$$ \begin{align} \text{Cov}(W(s), W(t)) &= E[W(s) W(t)] – E[W(s)] E[W(t)] \\ &= E[W(s) W(t)] \\ &= E[W(s)(W(t) – W(s) + W(s))] \\ &= E[W(s)(W(t) – W(s))] + E[W(s)^2] \\ &= E[W(s)] \cdot E[W(t) – W(s)] + \text{Var}(W(s)) \quad (\because \text{独立増分}) \\ &= 0 \cdot 0 + s \\ &= s \end{align} $$

4行目で、$W(s) = W(s) – W(0)$ と $W(t) – W(s)$ が独立(独立増分性より)であることを用いました。一般に、

$$ \text{Cov}(W(s), W(t)) = \min(s, t) $$

性質3: ガウス過程

条件(B2)(B3)より、ブラウン運動の任意の有限次元分布は多次元正規分布に従います。つまり、ブラウン運動は平均関数 $\mu(t) = 0$、共分散関数 $C(s, t) = \min(s, t)$ のガウス過程です。

性質4: 定常増分

$W(t) – W(s) \sim N(0, t – s)$ なので、増分の分布は開始時刻 $s$ には依存せず、時間差 $t – s$ のみに依存します。この性質を 定常増分(stationary increments) と呼びます。

マルコフ性

命題: ブラウン運動はマルコフ性を持つ。

証明: 独立増分性から、$W(t) – W(s)$ は $\{W(u) : u \leq s\}$ と独立です。したがって、$W(t) = W(s) + (W(t) – W(s))$ の条件付き分布は $W(s)$ の値のみに依存し、$\{W(u) : u < s\}$ には依存しません。

$$ P(W(t) \leq x \mid W(s) = w, W(u) = w_u, u < s) = P(W(t) \leq x \mid W(s) = w) $$

より具体的には、$W(s) = w$ が与えられたとき、

$$ W(t) \mid W(s) = w \sim N(w, t – s) $$

です。これはマルコフ性の定義そのものです。$\square$

マルチンゲール性

命題: ブラウン運動 $\{W(t)\}$ は $\{\mathcal{F}_t\}$-マルチンゲールである。ここで $\mathcal{F}_t = \sigma(W(s) : s \leq t)$ は自然フィルトレーションとする。

証明: $s \leq t$ のとき、

$$ \begin{align} E[W(t) \mid \mathcal{F}_s] &= E[W(s) + (W(t) – W(s)) \mid \mathcal{F}_s] \\ &= W(s) + E[W(t) – W(s) \mid \mathcal{F}_s] \\ &= W(s) + E[W(t) – W(s)] \quad (\because \text{独立増分性: } W(t) – W(s) \perp \mathcal{F}_s) \\ &= W(s) + 0 \\ &= W(s) \end{align} $$

よって $E[W(t) \mid \mathcal{F}_s] = W(s)$ であり、マルチンゲールの定義を満たします。$\square$

ランダムウォークからの構成

対称ランダムウォーク

独立同分布な確率変数列 $\{Y_k\}_{k=1}^{\infty}$ で、$P(Y_k = +1) = P(Y_k = -1) = 1/2$ とします。対称ランダムウォークは、

$$ S_n = \sum_{k=1}^{n} Y_k, \quad S_0 = 0 $$

で定義されます。$E[Y_k] = 0$、$\text{Var}(Y_k) = 1$ です。

スケーリングされたランダムウォーク

ランダムウォークの時間と空間をスケーリングして、連続時間の過程に変換します。パラメータ $n$(分割の細かさ)に対して、

$$ W^{(n)}(t) = \frac{1}{\sqrt{n}} S_{\lfloor nt \rfloor}, \quad t \geq 0 $$

ここで $\lfloor nt \rfloor$ は $nt$ の整数部分です。直感的には、

  • 時間のスケーリング: 1ステップを $1/n$ の時間に圧縮
  • 空間のスケーリング: $1/\sqrt{n}$ で縮小

この $1/\sqrt{n}$ というスケーリングは、中心極限定理から自然に導かれます。

Donskerの不変原理

定理(Donsker, 1951): $n \to \infty$ のとき、$W^{(n)}(t)$ はブラウン運動 $W(t)$ に 分布収束(convergence in distribution) する。

より正確には、$C[0, 1]$($[0, 1]$ 上の連続関数空間)上の確率測度として弱収束します。

直感的な説明: 中心極限定理により、$S_n / \sqrt{n} \to N(0, 1)$ が成り立ちます。Donskerの定理はこれを「各時刻での分布の収束」から「過程全体(パスの空間上の確率測度)の収束」に拡張したものです。

有限次元分布の収束を確認してみましょう。固定された $t > 0$ に対して、

$$ W^{(n)}(t) = \frac{1}{\sqrt{n}} S_{\lfloor nt \rfloor} = \frac{1}{\sqrt{n}} \sum_{k=1}^{\lfloor nt \rfloor} Y_k $$

中心極限定理より、

$$ \frac{S_{\lfloor nt \rfloor}}{\sqrt{\lfloor nt \rfloor}} \xrightarrow{d} N(0, 1) $$

$\lfloor nt \rfloor / n \to t$ なので、

$$ W^{(n)}(t) = \frac{\sqrt{\lfloor nt \rfloor}}{\sqrt{n}} \cdot \frac{S_{\lfloor nt \rfloor}}{\sqrt{\lfloor nt \rfloor}} \xrightarrow{d} \sqrt{t} \cdot N(0, 1) = N(0, t) $$

確かにブラウン運動の周辺分布 $W(t) \sim N(0, t)$ に一致します。

ブラウン運動の性質

連続だが至る所微分不可能

ブラウン運動の最も驚くべき性質の一つは、サンプルパスが 連続だが至る所微分不可能 であることです。

定理: 標準ブラウン運動のサンプルパスは、確率1でどの点 $t$ においても微分不可能である。

証明スケッチ: もし $W(t)$ が時刻 $t_0$ で微分可能であれば、

$$ \lim_{h \to 0} \frac{W(t_0 + h) – W(t_0)}{h} $$

が存在して有限値をとるはずです。しかし、$W(t_0 + h) – W(t_0) \sim N(0, h)$ なので、

$$ \frac{W(t_0 + h) – W(t_0)}{h} \sim N\left(0, \frac{1}{h}\right) $$

この分散 $1/h$ は $h \to 0$ で $\infty$ に発散します。つまり、$h$ が小さくなるにつれて差分商の変動が大きくなり、極限が存在しません。

より厳密には、任意の固定された $t_0$ に対して、$h_n = 1/n$ として

$$ \frac{W(t_0 + h_n) – W(t_0)}{h_n} $$

の分散は $n$ に等しく、$n \to \infty$ で発散します。ボレル=カンテリの補題を用いた精密な議論により、確率1で全ての $t$ において微分不可能であることが示されます。$\square$

2次変分

定義: 区間 $[0, t]$ の分割 $\Pi = \{0 = t_0 < t_1 < \cdots < t_n = t\}$ に対して、2次変分(quadratic variation)

$$ [W, W]_t^{(\Pi)} = \sum_{k=0}^{n-1} (W(t_{k+1}) – W(t_k))^2 $$

と定義されます。

定理: 分割を細かくする極限($|\Pi| = \max_k(t_{k+1} – t_k) \to 0$)で、

$$ [W, W]_t = \lim_{|\Pi| \to 0} \sum_{k=0}^{n-1} (W(t_{k+1}) – W(t_k))^2 = t $$

が $L^2$ 収束(および確率収束)の意味で成り立ちます。

証明: 等間隔分割 $t_k = kt/n$ の場合を示します。$\Delta W_k = W(t_{k+1}) – W(t_k) \sim N(0, t/n)$ と書くと、これらは独立です。

$$ Q_n = \sum_{k=0}^{n-1} (\Delta W_k)^2 $$

期待値を計算します。

$$ E[Q_n] = \sum_{k=0}^{n-1} E[(\Delta W_k)^2] = \sum_{k=0}^{n-1} \frac{t}{n} = t $$

分散を計算します。$\Delta W_k \sim N(0, t/n)$ より $E[(\Delta W_k)^4] = 3(t/n)^2$ なので、

$$ \text{Var}((\Delta W_k)^2) = E[(\Delta W_k)^4] – (E[(\Delta W_k)^2])^2 = 3\left(\frac{t}{n}\right)^2 – \left(\frac{t}{n}\right)^2 = 2\left(\frac{t}{n}\right)^2 $$

独立性より、

$$ \text{Var}(Q_n) = \sum_{k=0}^{n-1} \text{Var}((\Delta W_k)^2) = n \cdot 2\left(\frac{t}{n}\right)^2 = \frac{2t^2}{n} $$

$n \to \infty$ で $\text{Var}(Q_n) \to 0$ なので、

$$ E[(Q_n – t)^2] = \text{Var}(Q_n) = \frac{2t^2}{n} \to 0 $$

よって $Q_n \to t$ が $L^2$ 収束の意味で成り立ちます。$\square$

この結果は、形式的に $(dW)^2 = dt$ と書かれ、伊藤の公式の導出において本質的な役割を果たします。通常の微分可能な関数では2次変分は0ですが、ブラウン運動では0ではないことが、確率微積分が通常の微積分と異なる根本的な理由です。

1次変分は無限大

定理: ブラウン運動の 1次変分(total variation) は確率1で無限大である。

$$ \sum_{k=0}^{n-1} |W(t_{k+1}) – W(t_k)| \to \infty \quad (|\Pi| \to 0) $$

証明スケッチ: コーシー=シュワルツの不等式より、

$$ \sum_{k} |W(t_{k+1}) – W(t_k)| \geq \frac{\sum_{k} (W(t_{k+1}) – W(t_k))^2}{\max_k |W(t_{k+1}) – W(t_k)|} $$

分子は $t$ に収束し、分母はパスの連続性より0に収束するため、左辺は $\infty$ に発散します。$\square$

スケーリング不変性

定理: $c > 0$ に対して、$\tilde{W}(t) = \frac{1}{\sqrt{c}} W(ct)$ は再びブラウン運動である。

証明: 4条件を確認します。

(B1) $\tilde{W}(0) = W(0)/\sqrt{c} = 0$ ✓

(B2) $\tilde{W}(t) – \tilde{W}(s) = \frac{1}{\sqrt{c}}(W(ct) – W(cs))$ で、$W$ の独立増分性から $\tilde{W}$ も独立増分 ✓

(B3) $\tilde{W}(t) – \tilde{W}(s) = \frac{1}{\sqrt{c}}(W(ct) – W(cs)) \sim \frac{1}{\sqrt{c}} N(0, c(t-s)) = N(0, t-s)$ ✓

(B4) $W$ が連続なので $\tilde{W}$ も連続 ✓ $\square$

時間反転対称性

定理: $\tilde{W}(t) = W(T – t) – W(T)$($0 \leq t \leq T$)は $[0, T]$ 上のブラウン運動である。

ブラウン運動を「時間を逆にして見ても」同じ統計的性質を持ちます。

幾何ブラウン運動

定義と動機

金融工学では、株価のような常に正の値をとる変量をモデル化する必要があります。ブラウン運動自体は負の値もとるため、直接株価モデルには使えません。そこで、幾何ブラウン運動(geometric Brownian motion, GBM) が導入されます。

定義: 幾何ブラウン運動 $\{S(t)\}$ は、

$$ S(t) = S(0) \exp\left[\left(\mu – \frac{\sigma^2}{2}\right)t + \sigma W(t)\right] $$

で定義されます。ここで $\mu$ はドリフト、$\sigma$ はボラティリティです。

これは確率微分方程式

$$ dS = \mu S \, dt + \sigma S \, dW $$

の解です(伊藤の公式を用いて導出されますが、詳細は次の記事で扱います)。

GBMの性質

$S(t)$ は $W(t) \sim N(0, t)$ の関数なので、$\ln S(t)$ は正規分布に従います。

$$ \ln S(t) = \ln S(0) + \left(\mu – \frac{\sigma^2}{2}\right)t + \sigma W(t) \sim N\left(\ln S(0) + \left(\mu – \frac{\sigma^2}{2}\right)t, \sigma^2 t\right) $$

したがって $S(t)$ は 対数正規分布 に従います。

期待値を計算します。

$$ \begin{align} E[S(t)] &= S(0) \cdot E\left[\exp\left(\left(\mu – \frac{\sigma^2}{2}\right)t + \sigma W(t)\right)\right] \\ &= S(0) \cdot \exp\left(\left(\mu – \frac{\sigma^2}{2}\right)t\right) \cdot E[\exp(\sigma W(t))] \end{align} $$

ここで $W(t) \sim N(0, t)$ の積率母関数を用いると、

$$ E[\exp(\sigma W(t))] = \exp\left(\frac{\sigma^2 t}{2}\right) $$

したがって、

$$ E[S(t)] = S(0) \exp(\mu t) $$

ドリフト $\mu$ が正であれば、株価の期待値は指数関数的に成長します。

ブラウン橋

定義

ブラウン橋(Brownian bridge) $\{B(t)\}_{0 \leq t \leq 1}$ は、$B(0) = 0$ かつ $B(1) = 0$ という条件を課したブラウン運動です。

ブラウン運動 $\{W(t)\}$ を用いて、

$$ B(t) = W(t) – t \cdot W(1), \quad 0 \leq t \leq 1 $$

と構成できます。

性質の導出

平均: $E[B(t)] = E[W(t)] – t \cdot E[W(1)] = 0$

共分散: $s \leq t$ のとき、

$$ \begin{align} \text{Cov}(B(s), B(t)) &= \text{Cov}(W(s) – sW(1), W(t) – tW(1)) \\ &= \text{Cov}(W(s), W(t)) – t \cdot \text{Cov}(W(s), W(1)) – s \cdot \text{Cov}(W(1), W(t)) + st \cdot \text{Cov}(W(1), W(1)) \end{align} $$

$\text{Cov}(W(s), W(t)) = \min(s, t)$ を用いると、

$$ \begin{align} \text{Cov}(B(s), B(t)) &= s – t \cdot s – s \cdot t + st \cdot 1 \\ &= s – st \\ &= s(1 – t) \end{align} $$

一般に $s \leq t$ のとき、

$$ \text{Cov}(B(s), B(t)) = \min(s, t) – st $$

分散: $\text{Var}(B(t)) = t(1 – t)$ であり、$t = 1/2$ で最大値 $1/4$ をとります。

Pythonでの実装

ランダムウォークからブラウン運動への収束

Donskerの不変原理を視覚的に確認します。

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42)

fig, axes = plt.subplots(2, 2, figsize=(14, 10))

# ランダムウォークのスケーリング: W^(n)(t) = S_{floor(nt)} / sqrt(n)
n_values = [10, 100, 1000, 10000]

for idx, n in enumerate(n_values):
    ax = axes[idx // 2][idx % 2]

    # 5つのサンプルパスを生成
    for path_idx in range(5):
        # 対称ランダムウォーク
        steps = np.random.choice([-1, 1], size=n)
        S = np.cumsum(steps)
        S = np.insert(S, 0, 0)

        # スケーリング
        t_scaled = np.arange(n + 1) / n
        W_scaled = S / np.sqrt(n)

        ax.plot(t_scaled, W_scaled, alpha=0.7, linewidth=0.8)

    ax.set_title(f"Scaled Random Walk (n={n})")
    ax.set_xlabel("t")
    ax.set_ylabel("$W^{(n)}(t)$")
    ax.axhline(y=0, color='k', linestyle='--', linewidth=0.5)
    ax.grid(True, alpha=0.3)

plt.suptitle("Donsker's Invariance Principle: Random Walk → Brownian Motion",
             fontsize=14, y=1.01)
plt.tight_layout()
plt.savefig("donsker_convergence.png", dpi=150, bbox_inches="tight")
plt.show()

$n$ が大きくなるにつれて、スケーリングされたランダムウォークのパスが滑らかなブラウン運動に近づいていく様子が観察できます。

ブラウン運動の性質の数値検証

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42)

# ブラウン運動の生成
T = 1.0
n_points = 10000
dt = T / n_points
t = np.linspace(0, T, n_points + 1)

n_paths = 1000  # 多数のサンプルパスでアンサンブル統計量を推定

# サンプルパスの生成
paths = np.zeros((n_paths, n_points + 1))
for i in range(n_paths):
    dW = np.random.normal(0, np.sqrt(dt), size=n_points)
    paths[i, 1:] = np.cumsum(dW)

fig, axes = plt.subplots(2, 2, figsize=(14, 10))

# (1) サンプルパスの表示
for i in range(10):
    axes[0, 0].plot(t, paths[i], alpha=0.5, linewidth=0.5)
# ±2σ の帯
axes[0, 0].fill_between(t, -2 * np.sqrt(t), 2 * np.sqrt(t),
                        alpha=0.15, color='red', label='±2σ = ±2√t')
axes[0, 0].set_title("Brownian Motion: Sample Paths")
axes[0, 0].set_xlabel("t")
axes[0, 0].set_ylabel("W(t)")
axes[0, 0].legend()
axes[0, 0].grid(True, alpha=0.3)

# (2) E[W(t)] と Var[W(t)] の検証
mean_paths = np.mean(paths, axis=0)
var_paths = np.var(paths, axis=0)

axes[0, 1].plot(t, mean_paths, 'b-', linewidth=1.5, label='Sample mean E[W(t)]')
axes[0, 1].plot(t, var_paths, 'r-', linewidth=1.5, label='Sample var Var[W(t)]')
axes[0, 1].plot(t, np.zeros_like(t), 'b--', linewidth=1, label='Theory: E[W(t)]=0')
axes[0, 1].plot(t, t, 'r--', linewidth=1, label='Theory: Var[W(t)]=t')
axes[0, 1].set_title("Mean and Variance Verification")
axes[0, 1].set_xlabel("t")
axes[0, 1].set_ylabel("Value")
axes[0, 1].legend()
axes[0, 1].grid(True, alpha=0.3)

# (3) 2次変分の検証
# 1本のパスで分割数を変えて2次変分を計算
W_single = paths[0]
partition_sizes = [10, 50, 100, 500, 1000, 5000, 10000]
quad_vars = []

for n_part in partition_sizes:
    step = n_points // n_part
    indices = np.arange(0, n_points + 1, step)
    W_part = W_single[indices]
    qv = np.sum(np.diff(W_part)**2)
    quad_vars.append(qv)

axes[1, 0].semilogx(partition_sizes, quad_vars, 'bo-', linewidth=1.5,
                     markersize=6, label='Quadratic variation')
axes[1, 0].axhline(y=T, color='r', linestyle='--', linewidth=2,
                    label=f'Theory: [W,W]_T = {T}')
axes[1, 0].set_title("Quadratic Variation [W,W]_T")
axes[1, 0].set_xlabel("Number of partitions")
axes[1, 0].set_ylabel("[W,W]_T")
axes[1, 0].legend()
axes[1, 0].grid(True, alpha=0.3)

# (4) 増分の正規性検証(ヒストグラム)
t_check = 0.5
idx_check = int(t_check / dt)
increments = paths[:, idx_check]  # W(0.5) - W(0) = W(0.5)

x_range = np.linspace(-3, 3, 200)
from scipy.stats import norm
pdf_theory = norm.pdf(x_range, loc=0, scale=np.sqrt(t_check))

axes[1, 1].hist(increments, bins=50, density=True, alpha=0.7,
                color='steelblue', edgecolor='black', linewidth=0.5,
                label=f'W({t_check}) histogram')
axes[1, 1].plot(x_range, pdf_theory, 'r-', linewidth=2,
                label=f'N(0, {t_check}) density')
axes[1, 1].set_title(f"Distribution of W({t_check})")
axes[1, 1].set_xlabel("Value")
axes[1, 1].set_ylabel("Density")
axes[1, 1].legend()
axes[1, 1].grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig("brownian_motion_properties.png", dpi=150, bbox_inches="tight")
plt.show()

幾何ブラウン運動(株価モデル)

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42)

# パラメータ
S0 = 100       # 初期株価
mu = 0.1        # 年率ドリフト(期待リターン)
sigma = 0.3     # 年率ボラティリティ
T = 2.0         # 2年間
n_points = 500  # 時間刻み数
dt = T / n_points
t = np.linspace(0, T, n_points + 1)
n_paths = 1000

# 幾何ブラウン運動のサンプルパス生成
# S(t) = S(0) * exp((mu - sigma^2/2)*t + sigma*W(t))
GBM_paths = np.zeros((n_paths, n_points + 1))
GBM_paths[:, 0] = S0

for i in range(n_paths):
    dW = np.random.normal(0, np.sqrt(dt), size=n_points)
    W = np.cumsum(dW)
    for j in range(n_points):
        GBM_paths[i, j + 1] = S0 * np.exp((mu - sigma**2 / 2) * t[j + 1]
                                            + sigma * np.cumsum(dW)[j])

fig, axes = plt.subplots(1, 3, figsize=(18, 5))

# (1) サンプルパス
for i in range(20):
    axes[0].plot(t, GBM_paths[i], alpha=0.4, linewidth=0.5)
# 期待値の理論曲線
E_S = S0 * np.exp(mu * t)
axes[0].plot(t, E_S, 'r-', linewidth=2.5, label=f'E[S(t)] = {S0}e^{{{mu}t}}')
axes[0].set_title("Geometric Brownian Motion (Stock Price Model)")
axes[0].set_xlabel("Time (years)")
axes[0].set_ylabel("Price S(t)")
axes[0].legend()
axes[0].grid(True, alpha=0.3)

# (2) 終端価格の分布(対数正規分布)
final_prices = GBM_paths[:, -1]
axes[1].hist(final_prices, bins=50, density=True, alpha=0.7,
             color='steelblue', edgecolor='black', linewidth=0.5)

# 対数正規分布の理論密度
from scipy.stats import lognorm
mu_ln = np.log(S0) + (mu - sigma**2 / 2) * T
sigma_ln = sigma * np.sqrt(T)
x_range = np.linspace(0, max(final_prices) * 1.1, 300)
pdf_lognorm = lognorm.pdf(x_range, s=sigma_ln, scale=np.exp(mu_ln))
axes[1].plot(x_range, pdf_lognorm, 'r-', linewidth=2, label='Lognormal density')
axes[1].set_title(f"Distribution of S(T={T})")
axes[1].set_xlabel("Price")
axes[1].set_ylabel("Density")
axes[1].legend()
axes[1].grid(True, alpha=0.3)

# (3) 対数リターンの分布(正規分布)
log_returns = np.log(final_prices / S0)
axes[2].hist(log_returns, bins=50, density=True, alpha=0.7,
             color='steelblue', edgecolor='black', linewidth=0.5)

# 理論密度
from scipy.stats import norm
x_log = np.linspace(min(log_returns), max(log_returns), 200)
pdf_normal = norm.pdf(x_log, loc=(mu - sigma**2 / 2) * T, scale=sigma * np.sqrt(T))
axes[2].plot(x_log, pdf_normal, 'r-', linewidth=2, label='Normal density')
axes[2].set_title("Log Return ln(S(T)/S(0))")
axes[2].set_xlabel("Log return")
axes[2].set_ylabel("Density")
axes[2].legend()
axes[2].grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig("geometric_brownian_motion.png", dpi=150, bbox_inches="tight")
plt.show()

print(f"幾何ブラウン運動の統計量 (T={T}):")
print(f"  E[S(T)] 理論値: {S0 * np.exp(mu * T):.2f}")
print(f"  E[S(T)] 標本平均: {np.mean(final_prices):.2f}")
print(f"  Median 理論値: {S0 * np.exp((mu - sigma**2/2) * T):.2f}")
print(f"  Median 標本値: {np.median(final_prices):.2f}")

ブラウン橋のシミュレーション

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42)

T = 1.0
n_points = 1000
dt = T / n_points
t = np.linspace(0, T, n_points + 1)
n_paths = 20

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# --- ブラウン運動 ---
for i in range(n_paths):
    dW = np.random.normal(0, np.sqrt(dt), size=n_points)
    W = np.cumsum(dW)
    W = np.insert(W, 0, 0)
    axes[0].plot(t, W, alpha=0.5, linewidth=0.5)

axes[0].fill_between(t, -2*np.sqrt(t), 2*np.sqrt(t), alpha=0.1, color='red')
axes[0].set_title("Brownian Motion W(t)")
axes[0].set_xlabel("t")
axes[0].set_ylabel("W(t)")
axes[0].grid(True, alpha=0.3)

# --- ブラウン橋 B(t) = W(t) - t*W(1) ---
for i in range(n_paths):
    dW = np.random.normal(0, np.sqrt(dt), size=n_points)
    W = np.cumsum(dW)
    W = np.insert(W, 0, 0)
    # ブラウン橋の構成
    B = W - t * W[-1]
    axes[1].plot(t, B, alpha=0.5, linewidth=0.5)

# ±2σ の理論的な帯: σ(t) = sqrt(t(1-t))
sigma_bridge = np.sqrt(t * (1 - t))
axes[1].fill_between(t, -2*sigma_bridge, 2*sigma_bridge,
                     alpha=0.1, color='red', label='±2σ = ±2√(t(1-t))')
axes[1].set_title("Brownian Bridge B(t) = W(t) - tW(1)")
axes[1].set_xlabel("t")
axes[1].set_ylabel("B(t)")
axes[1].legend()
axes[1].grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig("brownian_bridge.png", dpi=150, bbox_inches="tight")
plt.show()

ブラウン橋は $t = 0$ と $t = 1$ で必ず0になるため、パスが「橋」のような形状を描きます。分散は $t(1-t)$ であり、中間時点 $t = 1/2$ で最大になります。統計学ではコルモゴロフ=スミルノフ検定の理論的基盤として、また金融工学では裁定取引の検出などに用いられます。

まとめ

本記事では、ブラウン運動(ウィーナー過程)の理論について包括的に解説しました。

  • ブラウン運動は4つの公理(初期条件、独立増分、正規増分、連続パス)で定義される
  • ランダムウォークの適切なスケーリング極限としてブラウン運動が得られる(Donskerの不変原理)
  • 共分散は $\text{Cov}(W(s), W(t)) = \min(s, t)$ であり、マルコフ性とマルチンゲール性を持つ
  • サンプルパスは連続だが至る所微分不可能であり、2次変分は $(dW)^2 = dt$ を満たす
  • 幾何ブラウン運動 $S(t) = S_0 \exp((\mu – \sigma^2/2)t + \sigma W(t))$ は株価モデルとして広く使われる
  • ブラウン橋は端点を固定したブラウン運動であり、統計検定の理論で重要

次のステップとして、以下の記事も参考にしてください。