アクチュアリーのためのPython入門(第7回)
Pythonで作る生命保険の将来収支(件数と保険金額の推移)
はじめに
ここまでの記事では、
- 生命表
- 基数表
- 給付現価
- 保険料・保険料積立金
と、「基本的な生命保険数理」の計算をPythonで実装してきました。
これからは少し視点を変えて、
将来収支(キャッシュ・フロー)を作っていきます。
今回は、
将来収支を専門とするソフトウェアで採用されている考え方を、
シンプルな形に落とし込み、将来収支モデルの入口を作ってみます。
今回のゴール
今回は、以下を作成します。
- 保有件数の推移
- 保有保険金額の推移
具体的には、
- 初期契約件数からスタート
- 死亡・解約を考慮して期末の保有件数を計算
- それに保険金額を掛けて金額ベースに変換
という、将来収支モデルの「骨格」だけを作ります。
※ 保険料収入、責任準備金(保険料積立金)、などは次回以降で扱います。
※ 本記事では、考え方を分かりやすくするために、
件数ベースで将来収支の流れを作成します。
実務で使われる将来収支ソフトウェアでは、
基本的に保険金額ベースで計算が行われています。
将来収支は「生命表の拡張」
将来収支というと難しく聞こえますが、
本質的には生命表の考え方を少し拡張したものです。
生命表では、
- 生存者数$l_x$
- 死亡者数$d_x$
を年齢ごとに追っていました。
将来収支では、これを
- 契約件数
- 保険金額
に置き換えるだけです。
前提条件
今回のモデルでは、次の前提を置きます。
- 初期契約件数:100,000件
- 各契約の保険金額:100万円(一定)
- 契約時年齢・性別:40歳男性
- 予定死亡率:前回までに使った生命表
- 解約率:年齢によらず年率2%
- 死亡指数:0.7
※ あくまで「構造理解」が目的なので、数値は単純化しています。
※ 死亡指数とは、予定死亡率に一定の係数を掛けて、
実際の死亡水準を調整するためのパラメータです。
死亡指数 = 実績死亡率 / 予定死亡率
件数ベースの残存率表を作成する
将来収支モデルの第一歩は、件数ベースの残存率表です。
考え方は以下の順番です。
- 期首の保有件数
- 死亡件数
- 解約件数
- 期末の保有件数
生命表と同様に、期末の保有件数は、
期末保有件数 = 期首保有件数 - 死亡件数 - 解約件数
となり、死亡件数は、
死亡件数 = 期首保有件数 × 死亡件数 × 死亡指数
解約件数は、
解約件数 = 期首保有件数 × 解約率
です。
Pythonでの件数の推移を作る
前回までの生命表と異なるのは、死亡指数kを死亡率に乗じること、
解約者数wxを計算して、期首保有件数から差し引くことです。
具体的なコードは次のとおりです。
# 年齢
ages = list(range(40, 50))
# 死亡率(標準生命表2018)
qx =[0.00118,0.00129,0.00140,0.00151,0.00163,0.00177,0.00194,0.00214,0.00236,0.00259]
# 解約率
qwx = [0.02] * len(qx)
# 死亡指数
k = 0.7
# 初期生存者数
l0 = 100000
# 生存者数を入れるリスト
lx = [l0]
# 死亡者数を入れるリスト
dx = []
# 解約者数を入れるリスト
wx = []
# 生命表の作成
for q, w in zip(qx, qwx):
# 死亡者数
next_d = lx[-1] * q * k
# 解約者数
next_w = lx[-1] * w
# 生存者数
next_l = lx[-1] - next_d - next_w
# 生存者数、死亡者数のリストの最後に追加
lx.append(next_l)
dx.append(next_d)
wx.append(next_w)
計算結果を確認してみます。
for age, l, d, w in zip(ages, lx, dx, wx):
print(age, round(l, 2), round(d, 2), round(w, 2))
40 100000 82.6 2000.0
41 97917.4 88.42 1958.35
42 95870.63 93.95 1917.41
43 93859.27 99.21 1877.19
44 91882.87 104.84 1837.66
45 89940.38 111.44 1798.81
46 88030.13 119.54 1760.6
47 86149.99 129.05 1723.0
48 84297.93 139.26 1685.96
49 82472.71 149.52 1649.45
保険金額ベースへの変換
件数ベースができれば、
保険金額ベースへの変換は簡単です。
件数に保険金額を乗じればいいだけです。
# 保険金額
amount = 1000000
# 保険金額の推移
lx_amt = [l * amount for l in lx]
dx_amt = [d * amount for d in dx]
wx_amt = [w * amount for w in wx]
for A in B の構文で、Bから1つずつ取り出して、Aに代入していきます。
lx_amtには、lxにamountを乗じたリストができます。dxもwxも同様です。
計算結果を確認してみます。
for age, l, d, w in zip(ages, lx_amt, dx_amt, wx_amt):
print(age, int(l), int(d), int(w))
40 100000000000 82600000 2000000000
41 97917400000 88419412 1958348000
42 95870632587 93953219 1917412651
43 93859266716 99209244 1877185334
44 91882872136 104838357 1837657442
45 89940376337 111436126 1798807526
46 88030132683 119544920 1760602653
47 86149985110 129052677 1722999702
48 84297932730 139260184 1685958654
49 82472713890 149523030 1649454277
まとめ
今回は、
- 将来収支モデルの全体像
- 件数・保険金額の推移
だけに絞りました。
次回は、この件数・保険金額の推移を使って、
- 保険料収入
- 保険金支出
- 解約返戻金
を加えて、保険収支の形にしていきます。