アクチュアリーのためのPython入門(数学編第2回)
予定死亡率の補整2
📚 アクチュアリーのためのPython入門
この記事はアクチュアリー数学編の一部です。
▶ 目次はこちら
▶ 逆引きガイドはこちら
はじめに
前回は、死亡率の補整として、標準生命表の作成過程を取り上げました。
1次補整の安全割増、2次補整のGrevilleの平滑化までを行いました。
今回は、3次補整の高齢外挿のGompertz-Makehamを取り上げます。
前回と同じく資料はアクチュアリー会の標準生命表2018の作成過程です。
3次補整
まずは生存者数を計算します。
しばらく端数処理は行わないので、
float型に変換しておきます。
死亡率は前回作成した2次補整後の死亡率を使います。
資料のとおり、まずは死力をLagrangeの補間公式で近似します。
# 3次補整(高齢外挿)
# 生存者数
lx = [1]
for t in range(0, 94):
q = float(q2[t]) # 端数処理をしないので、float型
lx_next = lx[t] * (1 - q)
lx.append(lx_next)
# 死力をLagrangeの補間公式で近似
mux = []
for t in range(0, 93):
mux.append((8 * (lx[t - 1] - lx[t + 1]) - (lx[t - 2] - lx[t + 2])) / (12 * lx[t]))
続いて、最小2乗法によるパラメータの推計をします。
誤差の2乗和を取り、その最小値を求める関数を作成したいのですが、
誤差の精度を少し上げたいので対数を戻り値としておきます。
その関数をsseとしておきます。
引数paramsはGompertz-Makehamのパラメータで、
A,B,Cが入る前提です。
# Gompertz-Makehamの最小2乗法の誤差
xmin = 81 # 年齢範囲下限
xmax = 92 # 年齢範囲上限
def sse(params):
parA, parB, parC = params
err = 0
for t in range(xmin, xmax + 1):
err += (parA + parB * math.exp(parC * (t - xmin)) - mux[t]) ** 2
# 精度を上げたいので、logを取る
return math.log(err)
ここで、アクチュアリー数学なら微分するのですが、
最小値を求める関数minimizeを使用します。
仕組みとしては、先のsseのパラメータparamsを動かして、
戻り値が小さくなる方向を探し、
最終的に最小値を探す力押しの方法です。
Excelだとゴールシークやソルバーが当たります。
新しいライブラリscipyを使いますので、
それをインストールしてください。
# 誤差の最小化
from scipy.optimize import minimize
次にminimizeで関数とパラメータの初期値x0、
最適化の方法methodと精度tolを指定します。
その結果をresultに代入させます。
ここでは、初期値を過去の経験から、
どの程度か知っている前提としています。
初期値なしから求めると、収束値が求まらなかったり、
計算に時間がかかったりします。
# パラメータの初期値と最小化
rresult = minimize(sse, x0 = [-0.015, 0.07, 0.1], method="Nelder-Mead", tol=1e-10)
parA, parB, parC, = result.x
結果を小数10桁まで表示すると、
-0.0151980782
0.0700064924
0.1032065226
となります。
結果は資料より誤差は少し大きいものの近い数値が出せました。
精度をあげたり、他の最適化の方法を試行したりすれば、
もっと資料の数値に近くなるかもしれませんが、
最小2乗法が解ければ、精度は別の話ですので、
これ以上はしていません。
続いて、求めたパラメータを使って、
Gompertz-Makehamで死亡率を計算します。
# Gompertz-Makehamで84歳で接続
q3 = []
for t in range(0, 110):
if t < 84:
q = q2[t]
else:
q = 1 - math.exp(-(parA + parB / parC * (math.exp(parC) - 1) * math.exp(parC * (t - xmin))))
q = roundhu(q, 5)
q3.append(q)
結果を見やすいようにDataFrame化します。
df2 = pd.DataFrame({
"age":range(0,110),
"q":q3
})
結果表示すると、
q
age
0 0.00081
1 0.00056
2 0.00036
3 0.00022
4 0.00014
.. ...
105 0.57800
106 0.61642
107 0.65494
108 0.69314
109 0.73057
パラメータが少しズレているので、
標準生命表とは少し違いますが、
生命表の補整を行うことができました。
まとめ
今回は予定死亡率の補整を再現しました。
使ったのは生命保険数学というよりは確率統計の分野です。
- 第1補整は正規分布の使用
- 第3補整は最小2乗法によるパラメータ推計
ここは他でも応用することができます。
📚 ナビゲーション
◀ 前の記事
予定死亡率の補整1
▶ 次の記事
予定死亡率の補整3
📚 目次
アクチュアリーのためのPython入門