アクチュアリーのためのPython入門(アクチュアリー数学編第6回)
破産確率とVaRのシミュレーション
📚 アクチュアリーのためのPython入門
この記事はアクチュアリー数学編の一部です。
▶ 目次はこちら
▶ 逆引きガイドはこちら
はじめに
前回は複合分布をシミュレーションを行い、
最終的に破産確率まで計算することができました。
ただ、前回の破産確率の計算は、
過去問の解答通りの確率分布をシミュレーションしただけで、
本当にこの公式どおりになるのかPythonで確認するには至っていません。
今回は、もとの条件に沿った形の破産確率を計算して、
公式と近い値が求められるということを確認しましょう。
過去問は前回と同じく2022年の損保数理の問題2(3)です。
破産確率
まずは、前回と同じ前提条件で、問題ともに同じですが、
問題ではクレーム件数のパラメータは$\lambda$となっていますので、
ここでは平均lam=1としておきます。
年間に1回のクレーム回数の意味です。
# 2022年2(3)
import numpy as np
np.random.seed(42)
u0 = 75
lam = 1
mu = 10
theta = 0.25
# 収入保険料
c = lam * mu * (1 + theta)
trial = 100000 # 試行回数
bankruptcy = 0 # 破産回数初期値
max_time = 200 # 計算する年数
計算する年数ですが、理論値の計算では期間を無限に近づけて、
収束値を取るのですが、シミュレーションではできませんので、
200年まで計算して破産するかを確認することにします。
試行回数は100,000回です。
次に破産確率の部分です。
ut = t0 = 75からはじめて、
クレーム件数が平均1のポアソン分布に従うので、
そのクレーム間隔は平均1の指数分布になります。
ですので、指数分布の乱数dtを生成して、
その間の収入保険料をc * dtとします。
そして、クレームが発生するので、
今度はクレーム額の平均10の指数分布の乱数を生成し、
収入保険料を加えた後のutから差し引きます。
whileはt < max_timeの間は繰り返すの意味です。
for i in range(trial):
ut = u0
t = 0
while t < max_time:
# クレーム間隔
dt = np.random.exponential(scale = 1/lam)
t += dt
# 収入保険料
ut += c * dt
# クレーム額
claim_x = np.random.exponential(scale = 10)
# クレーム後
ut -= claim_x
最後にutがマイナスなら、
破産回数を+1して、breakでwhileのループから抜けます。
if ut < 0:
bankruptcy += 1
break
この計算で、結果がどうなるか確認してみます。
print(bankruptcy / trial)
0.17888
と、理論値と少し離れていますが、近い数値となります。
なお、1000年にすると、0.17853とほぼ理論値が出てきますが、
最大で1000年×100000回の計算をしていることになるので、
さすがのPythonでも計算終了までかなり時間がかかります。
以上で、公式で破産確率を導き出せていることが分かります。
対数正規分布
上記は理論値が公式を使って計算できますが、
今度は、理論値が簡単には計算できない
ポアソン分布+対数正規分布をシミュレーションしてみることにします。
この複合分布は簡単な関数では表せないので、
破産確率をシミュレーションで計算した方が早いです。
今回は、その複合分布のVaR95%、TVaR95%を計算してみます。
# ポアソン分布と対数正規分布の複合分布
import numpy as np
import pandas as pd
np.random.seed(42)
claim_n = np.random.poisson(lam=4, size=100000)
result = []
for n in claim_n:
claim_sum = 0
claim_x = np.random.lognormal(mean=0, sigma=1, size=n)
claim_sum = sum(claim_x)
result.append(claim_sum)
df = pd.DataFrame(result, columns=["claim_sum"])
# VaR95%
var95 = df["claim_sum"].quantile(0.95)
print(var95)
# TVaR95%
tvar95 = df.loc[df["claim_sum"] > var95, "claim_sum"].mean()
print(tvar95)
VaRとTVaRは次のとおりです。
16.750791157202485
22.276998163980704
ヒストグラムを確認すると次のようになります。
まとめ
今回は、破産確率を基本に戻って計算してみました。
また、複雑な複合分布の例として、
ポアソン分布+対数正規分布のVaR、TVaRを計算してみました。
対数正規分布の複合分布のように簡単な関数で表せない場合は、
実際にシミュレーションを行って、VaRやTVaRを計算することがあります。
Pythonはいくつもの関数の乱数が生成できること、
繰り返し計算に強いことから、シミュレーションではよく使われます。
📚 ナビゲーション
◀ 前の記事
複合分布
▶ 次の記事
閾値超過モデル
📚 目次
アクチュアリーのためのPython入門