マルチンゲール収束定理と応用

公平なコイン投げを繰り返して累積損益を記録すると、その軌道はランダムウォークになります。このランダムウォークは時間が経つにつれてどんどん大きく振動し、一つの値に落ち着く気配がありません。ところが、「公平なゲーム」であっても、ある条件を加えると振る舞いが劇的に変わります。累積損益が常に非負であるという条件を加えた非負マルチンゲールは、驚くべきことにほぼ確実にある有限の値に収束するのです。

この結果を厳密に述べたのがマルチンゲール収束定理(Martingale Convergence Theorem)です。この定理は確率論の最も基本的かつ深い結果の一つであり、その応用は驚くほど広範です。

  • 確率論: 大数の強法則の証明、条件付き期待値の理論的基盤として使われます
  • 金融工学: リスク中立測度のもとでの資産価格の収束性を保証します
  • 統計学: ベイズ推定における事後分布の一致性(大標本での収束)を示すのに使われます
  • 生物学: 分岐過程における集団の運命(絶滅か無限増殖か)を決定するために不可欠です
  • 情報理論: シャノンの情報量のマルチンゲール的な性質に応用されます

本記事では、マルチンゲール収束定理を直感的に理解し、ドゥーブの上向き交差不等式を用いた証明のエッセンスを解説します。さらに、ポリアの壺や分岐過程など具体的な応用をPythonシミュレーションで確認します。

本記事の内容

  • マルチンゲールの復習と収束が直感的に期待される理由
  • ドゥーブのマルチンゲール収束定理の主張
  • 上向き交差不等式と証明のエッセンス
  • ポリアの壺への応用
  • 分岐過程における絶滅確率への応用
  • Pythonによるシミュレーションと検証

前提知識

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

マルチンゲールの復習と収束の直感

マルチンゲールの定義

マルチンゲールで学んだように、確率過程 $\{M_n\}_{n \geq 0}$ がフィルトレーション $\{\mathcal{F}_n\}$ に関するマルチンゲールであるとは、次の3条件を満たすことです。

  1. $M_n$ は $\mathcal{F}_n$-可測(適合過程)
  2. $E[|M_n|] < \infty$(可積分性)
  3. $E[M_{n+1} | \mathcal{F}_n] = M_n$(マルチンゲール条件 — 公平なゲーム)

条件3を $E[M_{n+1} | \mathcal{F}_n] \leq M_n$ に弱めると上マルチンゲール(supermartingale)、$E[M_{n+1} | \mathcal{F}_n] \geq M_n$ に変えると下マルチンゲール(submartingale)になります。

どのようなマルチンゲールが収束するのか

すべてのマルチンゲールが収束するわけではありません。最も単純な例として、対称ランダムウォーク $S_n = \sum_{k=1}^n X_k$($X_k = \pm 1$ を等確率でとる)はマルチンゲールですが、$n \to \infty$ で収束しません。$S_n$ は $\pm\infty$ の間を際限なく行き来します。

一方、非負マルチンゲール($M_n \geq 0$ a.s.)を考えると、事情が大きく変わります。非負という制約は「下からのバリア」として機能し、過程の振動を制限します。直感的に考えてみましょう。

  • 非負マルチンゲールの値がゼロに近づくと、もうこれ以上大きく下がることはできません
  • マルチンゲール性(公平なゲーム)から、平均的には現在の値にとどまります
  • しかし非負制約によって下方向への動きが制限されるため、振動の幅は徐々に制限されます

大雑把に言えば、非負マルチンゲールは「底があるから、いつまでも暴れ続けることができない」のです。もう少し正確に言えば、非負マルチンゲールが上下に際限なく振動するためには膨大なエネルギーが必要ですが、期待値が一定(マルチンゲール性)という制約のもとではそのエネルギーが枯渇し、振動は止まるのです。

この直感を厳密に定理として述べたのが、次のドゥーブの収束定理です。

ドゥーブのマルチンゲール収束定理

定理の主張

ドゥーブのマルチンゲール収束定理: $\{M_n\}_{n \geq 0}$ が上マルチンゲール(特にマルチンゲール)で、

$$ \sup_n E[M_n^+] < \infty $$

が成り立つとき(ここで $M_n^+ = \max(M_n, 0)$)、ほぼ確実に有限な確率変数 $M_\infty$ が存在して、

$$ \begin{equation} M_n \xrightarrow{n \to \infty} M_\infty \quad \text{a.s. (almost surely)} \end{equation} $$

が成り立ちます。

系(非負マルチンゲール): $M_n \geq 0$ a.s. ならば $M_n^+ = M_n$ であり、$E[M_n^+] = E[M_n] \leq E[M_0]$(上マルチンゲール性)なので、条件は自動的に満たされます。

つまり、非負マルチンゲールは必ずほぼ確実に収束するのです。

定理の意味についての注意

収束定理にはいくつかの注意すべき点があります。

  1. 収束は「ほぼ確実に」(a.s.)である。すなわち、確率1で収束しますが、確率0の例外的なパスでは収束しないかもしれません

  2. $L^1$ 収束は保証されない。$M_n \to M_\infty$ a.s. であっても、$E[|M_n – M_\infty|] \to 0$ とは限りません。$L^1$ 収束を保証するには、一様可積分性(uniform integrability)という追加条件が必要です

  3. 極限 $M_\infty$ が非退化であるとは限らない。$M_\infty = 0$ a.s. という退化した収束もあり得ます。たとえば、次節で見る分岐過程の正規化マルチンゲールは、しばしば $M_\infty = 0$ に収束します

  4. $E[M_\infty]$ は $E[M_0]$ 以下である。ファトゥーの補題により $E[M_\infty] \leq \liminf_n E[M_n]$(上マルチンゲールの場合 $E[M_n]$ は単調減少列なので、$E[M_\infty] \leq E[M_0]$)です。等号が成り立つのは一様可積分な場合に限ります

これらの微妙な区別を理解することが、収束定理を正しく応用するために不可欠です。次に、証明の核心となるドゥーブの上向き交差不等式を見てみましょう。

上向き交差不等式と証明のエッセンス

上向き交差とは

実数値の数列 $x_0, x_1, x_2, \dots$ が値 $a$ を下から上に横切る回数を考えます。より正確には、区間 $[a, b]$($a < b$)の上向き交差(upcrossing)の回数 $U_n([a, b])$ を次のように定義します。

$a$ を下回った後に $b$ を上回ることを1回の上向き交差と数えます。形式的には、停止時刻の列を次のように帰納的に定義します。

$$ \begin{aligned} \tau_1 &= \min\{k \geq 0 : x_k \leq a\} \\ \sigma_1 &= \min\{k > \tau_1 : x_k \geq b\} \\ \tau_j &= \min\{k > \sigma_{j-1} : x_k \leq a\} \\ \sigma_j &= \min\{k > \tau_j : x_k \geq b\} \end{aligned} $$

$U_n([a, b])$ は、$n$ 時点までに完了した上向き交差の回数、すなわち $\sigma_j \leq n$ を満たす最大の $j$ です。

上向き交差の回数は、数列がどれだけ激しく振動しているかを測る量です。数列が収束するならば、任意の $[a, b]$ に対して上向き交差の回数は有限でなければなりません。逆に、もしある $[a, b]$ に対して上向き交差の回数が無限大になるならば、数列は収束しません。

ドゥーブの上向き交差不等式

ドゥーブの上向き交差不等式: $\{M_n\}$ が上マルチンゲールであるとき、

$$ \begin{equation} E[U_n([a, b])] \leq \frac{E[(M_n – a)^-]}{b – a} \end{equation} $$

ここで $(x)^- = \max(-x, 0)$ は負の部分を表します。

この不等式の直感的な意味は次の通りです。上マルチンゲールは平均的に減少する傾向にあるため、$a$ から $b$ への上向き交差を頻繁に行うことはできません。上向き交差のたびに少なくとも $b – a$ だけの「上昇」が必要ですが、上マルチンゲール性が「下降圧力」を加えるため、上向き交差の回数は制限されるのです。

証明のアイデア

上向き交差不等式を使って収束定理を証明するアイデアは、エレガントで直截的です。

ステップ1: $\sup_n E[M_n^+] < \infty$ の条件と上マルチンゲール性から、$E[(M_n - a)^-]$ が有界であることを示します。これは $|M_n| = 2M_n^+ - M_n$ であり、$E[|M_n|] \leq 2E[M_n^+] + |E[M_n]|$ と評価できることから従います。

ステップ2: 上向き交差不等式により、$E[U_n([a, b])]$ が $n$ によらない上界で押さえられます。単調収束定理から、

$$ E[U_\infty([a, b])] = \lim_{n \to \infty} E[U_n([a, b])] < \infty $$

期待値が有限なので、$U_\infty([a, b]) < \infty$ a.s. です。

ステップ3: すべての有理数 $a < b$ に対して $U_\infty([a, b]) < \infty$ a.s. であることから、$M_n$ がほぼ確実に収束することが従います。なぜなら、もし $M_n$ が収束しなければ、$\liminf M_n < \limsup M_n$ となる有理数 $a, b$ が存在し、$U_\infty([a, b]) = \infty$ となって矛盾するからです。

この証明は、「収束しない ⇒ 無限回の上向き交差 ⇒ 上向き交差不等式に矛盾」という対偶法を使っています。

理論を理解したところで、具体的な応用例を見ていきましょう。まずは古典的なポリアの壺の問題です。

応用1: ポリアの壺

問題の設定

ポリアの壺(Polya’s urn)は確率論の古典的な問題です。壺の中に赤い玉が $r$ 個、青い玉が $b$ 個入っています。以下の操作を繰り返します。

  1. 壺から1個の玉をランダムに取り出す
  2. 取り出した玉と同じ色の玉をもう1個追加して、2個を壺に戻す

$n$ 回目の操作の後、壺の中の赤い玉の割合を $R_n$ とします。$R_n$ はどのような振る舞いをするでしょうか。

マルチンゲール性の証明

$n$ 回の操作後、壺の中には合計 $r + b + n$ 個の玉があります。赤い玉の数を $r_n$ とすると、$R_n = r_n / (r + b + n)$ です。

$R_n$ がマルチンゲールであることを示します。$n$ 回目の操作の後で赤い玉が $r_n$ 個あるとき、次の操作で赤い玉を引く確率は $r_n/(r + b + n)$ です。

$$ E[R_{n+1} | \mathcal{F}_n] = \frac{r_n}{r + b + n} \cdot \frac{r_n + 1}{r + b + n + 1} + \frac{b_n}{r + b + n} \cdot \frac{r_n}{r + b + n + 1} $$

ここで $b_n = b + n – (r_n – r)$ は青い玉の数です。分子を展開すると、

$$ = \frac{r_n(r_n + 1) + b_n \cdot r_n}{(r + b + n)(r + b + n + 1)} = \frac{r_n(r_n + 1 + b_n)}{(r + b + n)(r + b + n + 1)} $$

$r_n + b_n = r + b + n$ であるから、$r_n + 1 + b_n = r + b + n + 1$ と代入すると、

$$ = \frac{r_n(r + b + n + 1)}{(r + b + n)(r + b + n + 1)} = \frac{r_n}{r + b + n} = R_n $$

したがって $E[R_{n+1} | \mathcal{F}_n] = R_n$ が成り立ち、$R_n$ はマルチンゲールです。

収束定理の適用

$R_n$ は赤い玉の割合なので $0 \leq R_n \leq 1$ です。非負でかつ有界なマルチンゲールなので、ドゥーブの収束定理により、

$$ R_n \xrightarrow{n \to \infty} R_\infty \quad \text{a.s.} $$

ある確率変数 $R_\infty$ に収束します。さらに、$R_\infty$ の分布は $\text{Beta}(r, b)$ であることが知られています。特に $r = b = 1$ の場合、$R_\infty$ は $[0, 1]$ 上の一様分布に従います。

この結果は直感的にも理解できます。初期に赤い玉が多く引かれると、赤い玉がさらに追加されて赤の割合が高くなりやすくなります(正のフィードバック)。この「富める者はさらに富む」効果により、割合は0と1の間のランダムな値に固定されるのです。

次に、もう一つの重要な応用である分岐過程を見てみましょう。

応用2: 分岐過程と絶滅確率

ガルトン・ワトソン過程

ガルトン・ワトソン過程(Galton-Watson process)は、各世代の個体が独立に子孫を残す分岐過程です。$Z_n$ を第 $n$ 世代の個体数、各個体の子孫数の分布を $\{p_k\}_{k \geq 0}$ とすると、

$$ Z_{n+1} = \sum_{i=1}^{Z_n} X_i^{(n)} $$

ここで $X_i^{(n)}$ は互いに独立で分布 $\{p_k\}$ に従います。

子孫数の期待値を $m = E[X] = \sum_k k p_k$ とすると、$E[Z_{n+1} | Z_n] = m Z_n$ です。

マルチンゲールの構成

$W_n = Z_n / m^n$ と正規化すると、$W_n$ はマルチンゲールになります。

$$ E[W_{n+1} | \mathcal{F}_n] = \frac{E[Z_{n+1} | \mathcal{F}_n]}{m^{n+1}} = \frac{m Z_n}{m^{n+1}} = \frac{Z_n}{m^n} = W_n $$

$W_n \geq 0$(個体数は非負)なので、マルチンゲール収束定理により、

$$ W_n \to W_\infty \quad \text{a.s.} $$

絶滅確率と $W_\infty$ の性質

$W_\infty$ の値は分岐過程の運命を決定します。

  • $m \leq 1$(臨界以下): $W_\infty = 0$ a.s. — 集団は確率1で絶滅します
  • $m > 1$(超臨界): $P(W_\infty > 0) = 1 – q$ — ここで $q$ は絶滅確率

超臨界の場合でも、$W_\infty = 0$ となる確率(絶滅確率 $q$)はゼロとは限りません。$q$ は母関数 $G(s) = \sum_k p_k s^k$ の不動点方程式 $G(q) = q$ の $[0, 1)$ における最小の解として決まります。

$W_\infty > 0$ の場合、集団は指数的に成長し、$Z_n \approx W_\infty \cdot m^n$ となります。$W_\infty$ は「初期のランダムな揺らぎによって決まる成長のスケール」を表しています。

これらの理論をPythonで検証してみましょう。

Pythonによるシミュレーションと検証

ポリアの壺のシミュレーション

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import beta as beta_dist

np.random.seed(42)

# --- パラメータ ---
r0 = 2  # 初期の赤い玉の数
b0 = 3  # 初期の青い玉の数
n_steps = 500
n_paths = 10000

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

# --- 左図: サンプルパス ---
ax = axes[0]
for i in range(20):
    r = r0
    b = b0
    ratios = [r / (r + b)]
    for step in range(n_steps):
        if np.random.random() < r / (r + b):
            r += 1  # 赤を引いた
        else:
            b += 1  # 青を引いた
        ratios.append(r / (r + b))
    ax.plot(range(n_steps + 1), ratios, linewidth=0.7, alpha=0.6)

ax.axhline(r0 / (r0 + b0), color='k', linestyle='--', linewidth=1, alpha=0.5,
           label=rf'$R_0 = {r0/(r0+b0):.2f}$')
ax.set_xlabel('Step $n$', fontsize=12)
ax.set_ylabel('Red fraction $R_n$', fontsize=12)
ax.set_title("Polya's urn: sample paths", fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)
ax.set_ylim(0, 1)

# --- 中図: 最終値の分布 ---
ax = axes[1]
final_ratios = []
for i in range(n_paths):
    r = r0
    b = b0
    for step in range(n_steps):
        if np.random.random() < r / (r + b):
            r += 1
        else:
            b += 1
    final_ratios.append(r / (r + b))

final_ratios = np.array(final_ratios)
ax.hist(final_ratios, bins=60, density=True, alpha=0.7, color='steelblue',
        edgecolor='white', linewidth=0.5, label='Simulation')

# Beta(r0, b0) の理論分布
x_beta = np.linspace(0.01, 0.99, 200)
ax.plot(x_beta, beta_dist.pdf(x_beta, r0, b0), 'r-', linewidth=2,
        label=rf'Beta({r0}, {b0})')
ax.set_xlabel('$R_\\infty$', fontsize=12)
ax.set_ylabel('Density', fontsize=12)
ax.set_title(f'Distribution of $R_\\infty$ ($n={n_steps}$)', fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)

# --- 右図: r0=1, b0=1 の場合(一様分布) ---
ax = axes[2]
final_ratios_11 = []
for i in range(n_paths):
    r = 1
    b = 1
    for step in range(n_steps):
        if np.random.random() < r / (r + b):
            r += 1
        else:
            b += 1
    final_ratios_11.append(r / (r + b))

ax.hist(final_ratios_11, bins=60, density=True, alpha=0.7, color='coral',
        edgecolor='white', linewidth=0.5, label='Simulation')
ax.axhline(1.0, color='r', linestyle='--', linewidth=1.5, label='Uniform(0,1)')
ax.set_xlabel('$R_\\infty$', fontsize=12)
ax.set_ylabel('Density', fontsize=12)
ax.set_title('$r_0 = b_0 = 1$: Uniform distribution', fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('polya_urn.png', dpi=150, bbox_inches='tight')
plt.show()

print(f"R_∞ の平均 (理論: {r0/(r0+b0):.4f}): {np.mean(final_ratios):.4f}")
print(f"R_∞ の分散 (理論: {r0*b0/((r0+b0)**2*(r0+b0+1)):.4f}): {np.var(final_ratios):.4f}")

ポリアの壺のシミュレーション結果から、以下のことが確認できます。

  1. 左図: 各パスが異なる値に収束している。初期の段階で「赤が多く出たか、青が多く出たか」によって、その後の軌道が大きく分かれます。これは正のフィードバック効果によるもので、マルチンゲール収束定理の帰結として各パスはほぼ確実にある値に収束します

  2. 中図: 極限分布がBeta$(r_0, b_0)$ 分布と正確に一致している。シミュレーションのヒストグラム(青)と理論的なBeta分布(赤い曲線)が重なっており、$R_\infty \sim \text{Beta}(r_0, b_0)$ であることが数値的に確認できます

  3. 右図: $r_0 = b_0 = 1$ の場合、極限分布は一様分布に従う。Beta$(1, 1)$ は一様分布なので、ヒストグラムが一定の高さ(密度1)のバーで満たされています。赤い玉と青い玉が1個ずつから始めると、最終的な赤の割合は $[0, 1]$ 上に一様に分布するという美しい結果です

分岐過程のシミュレーション

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(123)

# --- パラメータ: ポアソン分布の子孫数 ---
m_values = [0.8, 1.0, 1.5, 2.0]  # 平均子孫数
n_gen = 30      # 世代数
n_trials = 10000  # 試行数

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

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

    # W_n = Z_n / m^n のシミュレーション
    W_final = []
    extinct_count = 0

    for trial in range(n_trials):
        Z = 1  # 初期個体数
        extinct = False
        for gen in range(n_gen):
            if Z == 0:
                extinct = True
                break
            # 各個体の子孫数をポアソン分布で生成
            Z = np.sum(np.random.poisson(m, Z))
            if Z > 100000:  # 発散防止
                break
        if Z == 0:
            extinct_count += 1
            W_final.append(0.0)
        else:
            W_final.append(Z / m**n_gen)

    W_final = np.array(W_final)
    extinct_prob = extinct_count / n_trials

    # 絶滅確率の理論値(ポアソンの場合: q = G(q) の解)
    # G(s) = exp(m(s-1)) for Poisson(m)
    if m <= 1:
        q_theory = 1.0
    else:
        # ニュートン法で G(q) = q を解く
        q = 0.5
        for _ in range(100):
            G_q = np.exp(m * (q - 1))
            G_prime_q = m * G_q
            q = q - (G_q - q) / (G_prime_q - 1)
            q = max(0, min(q, 1))
        q_theory = q

    # ヒストグラム
    W_positive = W_final[W_final > 0.01]
    if len(W_positive) > 10:
        ax.hist(W_positive, bins=50, density=True, alpha=0.7, color='steelblue',
                edgecolor='white', linewidth=0.5, label=f'$W_\\infty > 0$')

    # 情報表示
    title = f'$m = {m}$'
    info = f'Extinct: {extinct_prob:.3f} (theory: {q_theory:.3f})'
    ax.set_title(title, fontsize=13)
    ax.text(0.95, 0.95, info, transform=ax.transAxes, fontsize=10,
            verticalalignment='top', horizontalalignment='right',
            bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))
    ax.set_xlabel('$W_\\infty = Z_n / m^n$', fontsize=11)
    ax.set_ylabel('Density', fontsize=11)
    ax.grid(True, alpha=0.3)
    if len(W_positive) > 10:
        ax.legend(fontsize=10)

plt.suptitle('Galton-Watson process: normalized population $W_n = Z_n / m^n$',
             fontsize=14, y=1.01)
plt.tight_layout()
plt.savefig('branching_process.png', dpi=150, bbox_inches='tight')
plt.show()

分岐過程のシミュレーション結果から、以下の理論的予測が確認できます。

  1. $m = 0.8$(劣臨界): 集団はほぼ確率1で絶滅します。理論的な絶滅確率は $q = 1$ であり、シミュレーションでもほぼすべての試行で絶滅が観察されます。$W_n \to 0$ a.s. です

  2. $m = 1.0$(臨界): 臨界の場合も絶滅確率は1ですが、絶滅までの時間は劣臨界の場合よりも長くなります。有限世代では絶滅していない試行もありますが、世代数を増やせば最終的にはすべて絶滅します

  3. $m = 1.5$(超臨界): 絶滅確率は1未満になります。$W_\infty > 0$ のパスでは集団が指数的に成長し、$W_\infty$ の分布はゼロでない連続分布になります。シミュレーションの絶滅確率が理論値とよく一致しています

  4. $m = 2.0$(強い超臨界): 絶滅確率はさらに低くなります。$W_\infty > 0$ の分布は $m = 1.5$ の場合よりも平均値が大きく、生き残った集団はより大きなスケールで成長します

上向き交差数の確認

最後に、ドゥーブの上向き交差不等式を数値的に確認します。

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(456)

def count_upcrossings(path, a, b):
    """パスの上向き交差数を数える"""
    below = False
    count = 0
    for x in path:
        if x <= a:
            below = True
        elif x >= b and below:
            count += 1
            below = False
    return count

# --- 非負マルチンゲール: |S_n| ここで S_n はランダムウォーク ---
# Doob変換で非負マルチンゲールを構成: M_n = (S_n + n + 1) は下マルチンゲール
# 代わりに簡単な例: M_n = exp(S_n - n*log(cosh(1)))

n_steps = 1000
n_paths = 20000

# 非負マルチンゲール: M_n = exp(θ S_n - n ψ(θ)) where ψ(θ) = log(cosh(θ))
theta_param = 0.5
psi = np.log(np.cosh(theta_param))

a_val = 0.5
b_val = 1.5

upcross_counts = []
max_neg_parts = []

for i in range(n_paths):
    steps = np.random.choice([-1, 1], size=n_steps)
    S = np.cumsum(steps)
    S = np.insert(S, 0, 0)
    M = np.exp(theta_param * S - np.arange(n_steps + 1) * psi)
    upcross_counts.append(count_upcrossings(M, a_val, b_val))
    max_neg_parts.append(np.max(np.maximum(a_val - M, 0)))

upcross_counts = np.array(upcross_counts)
max_neg_parts = np.array(max_neg_parts)

# 上向き交差不等式: E[U_n] <= E[(M_n - a)^-] / (b - a)
M_final_vals = []
for i in range(n_paths):
    steps = np.random.choice([-1, 1], size=n_steps)
    S = np.cumsum(steps)
    M_final = np.exp(theta_param * S[-1] - n_steps * psi)
    M_final_vals.append(M_final)

M_final_vals = np.array(M_final_vals)
neg_part_expectation = np.mean(np.maximum(a_val - M_final_vals, 0))
upcross_bound = neg_part_expectation / (b_val - a_val)

fig, axes = plt.subplots(1, 2, figsize=(13, 5.5))

# 上向き交差数の分布
ax = axes[0]
ax.hist(upcross_counts, bins=range(max(upcross_counts) + 2), density=True,
        alpha=0.7, color='steelblue', edgecolor='white', linewidth=0.5,
        align='left')
ax.axvline(np.mean(upcross_counts), color='b', linestyle='-', linewidth=2,
           label=f'Mean = {np.mean(upcross_counts):.2f}')
ax.axvline(upcross_bound, color='r', linestyle='--', linewidth=2,
           label=f'Upper bound = {upcross_bound:.2f}')
ax.set_xlabel(f'Upcrossings of [{a_val}, {b_val}]', fontsize=12)
ax.set_ylabel('Probability', fontsize=12)
ax.set_title("Doob's upcrossing inequality verification", fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)

# 非負マルチンゲールのサンプルパス
ax = axes[1]
for i in range(10):
    steps = np.random.choice([-1, 1], size=n_steps)
    S = np.cumsum(steps)
    S = np.insert(S, 0, 0)
    M = np.exp(theta_param * S - np.arange(n_steps + 1) * psi)
    ax.plot(range(n_steps + 1), M, linewidth=0.5, alpha=0.6)

ax.axhline(a_val, color='gray', linestyle='--', alpha=0.5, label=f'$a = {a_val}$')
ax.axhline(b_val, color='gray', linestyle=':', alpha=0.5, label=f'$b = {b_val}$')
ax.set_xlabel('Step $n$', fontsize=12)
ax.set_ylabel('$M_n$', fontsize=12)
ax.set_title('Non-negative martingale: sample paths', fontsize=13)
ax.legend(fontsize=9)
ax.grid(True, alpha=0.3)
ax.set_ylim(0, 5)

plt.tight_layout()
plt.savefig('upcrossing.png', dpi=150, bbox_inches='tight')
plt.show()

print(f"平均上向き交差数: {np.mean(upcross_counts):.4f}")
print(f"上向き交差不等式の上界: {upcross_bound:.4f}")
print(f"不等式は成立: {np.mean(upcross_counts) <= upcross_bound + 0.1}")

上向き交差のシミュレーション結果から、以下のことが確認できます。

  1. 左図: 平均上向き交差数が上界以下になっている。ドゥーブの上向き交差不等式 $E[U_n] \leq E[(M_n – a)^-]/(b – a)$ が数値的に成立していることが確認できます。実際の平均(青い実線)は上界(赤い破線)を下回っています

  2. 右図: 非負マルチンゲールのサンプルパスが収束する様子が見える。多くのパスは時間の経過とともにゼロ付近に近づいていますが、一部のパスは大きな値を取っています。非負という制約により、すべてのパスが有限の値に収束します(一部はゼロに、一部は正の値に)

収束定理の拡張と関連する結果

$L^p$ 収束

ドゥーブの収束定理はほぼ確実収束を保証しますが、$L^p$ 収束($p$乗期待値の意味での収束)は一般には成り立ちません。$L^p$ 収束が成り立つためには追加の条件が必要です。

$L^p$ マルチンゲール収束定理: $p > 1$ のとき、マルチンゲール $\{M_n\}$ が $\sup_n E[|M_n|^p] < \infty$ を満たすならば、$M_n$ は $M_\infty$ にほぼ確実かつ $L^p$ で収束します。

$p = 1$ の場合は一般に $L^1$ 収束が成り立ちません。$L^1$ 収束が成り立つためには一様可積分性(uniform integrability)が必要です。マルチンゲール $\{M_n\}$ が一様可積分であるとは、

$$ \lim_{c \to \infty} \sup_n E[|M_n| \cdot \mathbf{1}_{|M_n| > c}] = 0 $$

が成り立つことです。一様可積分なマルチンゲールは $L^1$ でも収束し、$E[M_n] = E[M_0]$ が極限でも保たれます。

レヴィの上向き定理

マルチンゲール収束定理の重要な帰結の一つがレヴィの上向き定理(Levy’s upward theorem)です。

$\mathcal{F}_n$ がフィルトレーション、$X$ が可積分確率変数のとき、条件付き期待値の列 $M_n = E[X | \mathcal{F}_n]$ はマルチンゲールです。$\mathcal{F}_\infty = \sigma(\bigcup_n \mathcal{F}_n)$ とすると、

$$ E[X | \mathcal{F}_n] \xrightarrow{n \to \infty} E[X | \mathcal{F}_\infty] \quad \text{a.s. and in } L^1 $$

この定理は、「情報が増えるにつれて条件付き期待値は真の値に近づく」ことを厳密に述べています。ベイズ統計において、データが増えるにつれて事後分布が真のパラメータに収束するという一致性(consistency)の証明にこの定理が使われます。

大数の強法則の証明

マルチンゲール収束定理を使って大数の強法則を証明できます。$X_1, X_2, \dots$ が独立同一分布で $E[X_1] = \mu$, $E[X_1^2] < \infty$ のとき、$S_n = \sum_{i=1}^n X_i$ とし、$M_n = S_n - n\mu$ はマルチンゲールです。$M_n/n$ の収束をマルチンゲール収束定理から導くことで、$S_n/n \to \mu$ a.s. が示されます。

この証明法は、独立性の仮定を弱めた場合(マルチンゲール差分列)にも拡張できるため、エルゴード理論や時系列解析でも活用されます。

まとめ

本記事では、マルチンゲール収束定理とその応用について解説しました。

  • ドゥーブの収束定理: $\sup_n E[M_n^+] < \infty$ を満たす上マルチンゲールはほぼ確実に収束します。特に非負マルチンゲールは常にこの条件を満たすため、必ず収束します
  • 上向き交差不等式: 上マルチンゲールが区間 $[a, b]$ を上向きに横切る回数の期待値に上界を与えます。この不等式が収束定理の証明の核心です
  • ポリアの壺: 赤い玉の割合は非負有界マルチンゲールであり、Beta分布に従う確率変数に収束します。正のフィードバック効果により、初期のランダムな揺らぎが最終的な割合を決定します
  • 分岐過程: 正規化された個体数 $W_n = Z_n/m^n$ は非負マルチンゲールであり、極限 $W_\infty$ の値が集団の運命(絶滅か生存か)を決定します
  • $L^p$ 収束と一様可積分性: ほぼ確実収束から $L^1$ 収束へのステップアップには一様可積分性が必要です
  • レヴィの上向き定理: 条件付き期待値は情報の増大とともにほぼ確実に $E[X|\mathcal{F}_\infty]$ に収束し、ベイズ推定の一致性を保証します
  • Pythonシミュレーションで、マルチンゲールの収束、ポリアの壺のBeta分布への収束、分岐過程の絶滅確率、上向き交差不等式を数値的に検証しました

マルチンゲール収束定理は、確率論の多くの深い結果(大数の強法則、レヴィの上向き定理、条件付き期待値の収束、ベイズ推定の一致性など)の証明に使われる基盤的な定理です。

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