Mímisbrunnr知恵の泉

← 数理最適化 一覧

🎓 レベル:発展 | 重要度:B(標準)

📎 前提:確率計画法サンプル平均近似(SAA) | 関連:ポートフォリオ最適化のモデル化

要点(BLUF)

概念 ── 平均だけ見ると危ない

確率計画(確率計画法)は期待値を最適化する。だが「平均は良いが、たまに破滅的損失」という解は、現実には受け入れがたい。リスク回避の意思決定には、テール(最悪側)のリスクを目的に織り込む必要がある。

VaR と CVaR

損失 L(x,ξ)L(x,\xi) の分布を考える。信頼水準 α\alpha(例 0.950.95)について:

graph LR
  A["損失分布"] --> B["VaR_α: α分位点(閾値)"]
  B --> C["CVaR_α: VaRを超える部分の平均"]
  C --> D["テールの重さを測る -> 最小化対象に"]

VaR は「どこまでで収まるか」だが、それを超えたときどれだけ酷いかは教えない。さらに VaR は 劣加法性を満たさない(分散投資でリスクが増えて見える)ので一貫したリスク尺度でない。CVaR はテールの平均を見るので、超過時の酷さを捉え、かつ 凸で一貫性のある(coherent)リスク尺度

Rockafellar–Uryasev の線形化

CVaR の定義は分位点を含み一見扱いにくいが、補助変数 τ\tau(VaR に対応)を導入すると 凸関数の最小化になる:

CVaRα=minτ {τ+11αE[(Lτ)+]}\text{CVaR}_\alpha = \min_{\tau}\ \left\{\, \tau + \frac{1}{1-\alpha}\,\mathbb{E}\bigl[(L-\tau)^+\bigr] \,\right\}

(Lτ)+=max(0,Lτ)(L-\tau)^+=\max(0,L-\tau)。シナリオ標本(サンプル平均近似(SAA))で期待値を置き換え、(Lτ)+(L-\tau)^+ を補助変数 zi0, ziLiτz_i\ge0,\ z_i\ge L_i-\tau で線形化すると、LP(または凸計画)になる:

minx,τ,z τ+1(1α)Ni=1Nzis.t.ziLi(x)τ, zi0\min_{x,\tau,z}\ \tau + \frac{1}{(1-\alpha)N}\sum_{i=1}^N z_i \quad \text{s.t.}\quad z_i \ge L_i(x)-\tau,\ z_i \ge 0

CVaR 最小化が凸問題に落ちる ── これが Rockafellar–Uryasev の貢献で、リスク管理を実用的にした。

Pythonで CVaR 最小ポートフォリオ

3資産、各リターンをシナリオでサンプリングし、損失(=負のリターン)の CVaR0.95\text{CVaR}_{0.95} を最小化する配分を求める。

import numpy as np
import cvxpy as cp

rng = np.random.default_rng(1)
n_assets, n_scen, alpha = 3, 2000, 0.95
# 各資産の平均リターンと分散(資産0が低リスク, 資産2が高リスク高リターン)
returns = rng.multivariate_normal([0.08, 0.10, 0.12],
                                  np.diag([0.02, 0.05, 0.09]), n_scen)
losses = -returns                                  # 損失 = -リターン

w   = cp.Variable(n_assets, nonneg=True)           # 資産配分
tau = cp.Variable()                                # VaR(閾値)に対応
z   = cp.Variable(n_scen, nonneg=True)             # 超過損失 (L - tau)^+

portfolio_loss = losses @ w
cvar = tau + (1/((1-alpha)*n_scen)) * cp.sum(z)    # Rockafellar-Uryasev
prob = cp.Problem(cp.Minimize(cvar),
                  [cp.sum(w) == 1, z >= portfolio_loss - tau])
prob.solve()

print(f"最小 CVaR_0.95 = {prob.value:.4f}")
print(f"最適配分 w = {np.round(w.value, 3)}  (資産0=低リスク, 資産2=高リスク)")

実行結果:

最小 CVaR_0.95 = 0.1387
最適配分 w = [0.6   0.274 0.126]

CVaR 最小化は、テールリスクを抑えるため 低リスク資産(資産0、分散0.02)に最も多く(60%)配分し、高リスク資産(資産2、分散0.09)は12.6%に抑えた。期待リターン最大化なら高リスク資産に全振りするところを、テールの平均損失を見ることで保守的な分散配分になる。リターンとのトレードオフを取るなら、期待リターン制約を加える(ポートフォリオ最適化のモデル化)。

数式の直観的意味

Rockafellar–Uryasev の式の美しさは、分位点(VaR)という 非凸・不連続な量を、補助変数 τ\tau の最小化を通じて 凸関数に変換した点。内側の τ+11αE[(Lτ)+]\tau+\frac1{1-\alpha}\mathbb{E}[(L-\tau)^+]τ\tau について凸(区分線形の期待値)で、最小を取る τ\tau^\star がちょうど VaR に一致し、最小値が CVaR になる。(Lτ)+(L-\tau)^+ は「閾値超過分だけ罰する」ヒンジ損失で、機械学習の SVM やペナルティ法(ペナルティ法・障壁法)と同じ構造。CVaR が凸で一貫性のあるリスク尺度であることが、xx(配分)について凸最適化を保証し、大域最適が得られる(凸集合と凸関数)。期待値最適化が分布の中心を見るのに対し、CVaR はテールの重さを見る ── 「平均的な良さ」と「最悪時の痛み」のどちらを最適化するかという、リスク態度の数理的表現。

⚠️ よくある誤解・落とし穴

関連ノート