Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
アクチュアリー会年次大会(2018年)
生命保険モデルの計算可能な仕様書についての考察
2018/11/9
株式会社ケーエーコンピューティング 門脇 大輔
要旨
1
レートやキャッシュフロー計算を行う生命保険モデルについて、簡潔かつコンピュータで計算可能な仕様書があれば、モデルの開発、ドキュメンテーションおよびコミュニケーションに有益
計算可能な仕様書に求められる要素について考察する。 必要となるDSL(ドメイン特化言語)およびグラフ理論などの技術についても考察する。
2
I 生命保険モデル・プロジェクションとは?
I-1 生命保険アクチュアリーの仕事
3
生命保険アクチュアリーの仕事とは? 商品開発 決算 リスク管理
I-2 プロジェクション
4
生命保険アクチュアリーの仕事の主な要素となるのがプロジェクション保険契約からもたらされるキャッシュフローを計算し、目的に応じて収益性・価値・リスク量といった値を求める。
商品開発個々の保険契約について計算し、収益性を求める。保険種類・タイプ・契約年齢・保険期間・払込期間などの属性のそれぞれの組み合わせごとに計算する。
決算(計理人の意見書) ・リスク管理会社全体の保険契約について計算する。金融商品としての価値や、一定のストレスシナリオが発現したときの価値の下落であるリスク量などを求める。
I-3 生命保険モデルとは?
5
インフォース、アサンプションを入力として、キャッシュフローを出力する関数
生命保険モデルは、以下の形で保持される。 ドキュメント(仕様書) Excelワークシート プロジェクションソフトウェアそれぞれの形式
インフォース
アサンプション生命保険モデル キャッシュフロー
I-4 生命保険モデルとは?(詳細)
6
インフォースの属性(保険種類、契約年齢、性別、保険期間、払込期間、保険金額など)
アサンプション死亡率・疾病発生率・解約率・金利など
キャッシュフローを出力する前の中間的な要素として、レートを計算する必要があるレート(保険金額あたりの保険料、責任準備金、解約返戻金など)
キャッシュフローキャッシュフロー(生命表、キャッシュフロー、責任準備金など)
キャッシュフローを計算した後、金利によって割引を行うなどの計算を行い、収益性・価値・リスク量を求める。
I-5 プロジェクションのイメージ
7
入力 - インフォース養老保険、契約年齢30歳、性別男性保険期間10年、払込期間10年、保険金額100万円
入力 - アサンプション(省略) 出力 - レート部分(保険金額1あたり)※数字は例です
出力 - キャッシュフロー部分 ※数字は例です
0 1 2 .. 9 10
保険料 0.11 - - - - -
責任準備金 0.00 0.09 0.19 .. 0.91 1.00
解約返戻金 0.00 0.01 0.13 .. 0.91 1.00
...
0 1 2 .. 9 10
保険料収入 - 110000 105000 - 70000 67000
死亡給付金 - 2000 2200 .. 3600 3800
解約返戻金 - 0 3000 .. 27000 30000
...
8
II 課題とソリューション
II-1 課題
9
生命保険モデルの開発・管理における課題
可読性 Excelワークシートは可読性に欠ける プロジェクションソフトの場合、そのソフトウェアの扱いやすさに依存する
モデルの管理 バージョン管理が難しい 差分比較が難しい
ドキュメンテーション 大事な部分が抜けていたりアップデート漏れがある 一意に解釈できないこともある
コミュニケーション 商品開発部門内でのレビュー、リスク管理部門でのレビューが行いづらい Excelモデルをそのまま読んで理解するのは非効率
II-2 ソリューション
10
「簡潔かつコンピュータで計算可能な仕様書」による解決を試みる
簡潔さ アクチュアリーが理解しやすい形での記述とする関数による記述、複数商品の管理に重複を無くす
テキスト形式による表現とする取り扱い・バージョン比較・差分比較が容易
計算可能であること モデルが一意に解釈できることが保証される 計算して結果を比較することで、そのモデルが適正にドキュメントされていることが保証される
どのように計算可能にするかは、III以降で説明する
II-3 簡潔さ - 関数による記述
11
関数による記述アクチュアリーは生命保険モデルを関数の集合として理解していると考え、その理解に近い形で表現する(どう計算するかのループを手続き的に意識しているわけではない)
(例)Dx(x) = lx(x) * v^xCx(x) = dx(x) * v^(x+0.5)Nx(x) = Nx(x+1) + Dx(x)Mx(x) = Mx(x+1) + Cx(x)生存者数(t) = lx(t-1) – d_x(t-1)保険料収入(t) = 保険料レート * 保険金額 * 生存者数(t)死亡給付(t) = 保険金額(t) * 死亡者数(t)責任準備金積増(t) = 責任準備金(t) – 責任準備金(t-1)
II-4 簡潔さ - 継承による複数商品の管理
12
アクチュアリーは複数の商品のモデルを、共通のロジックと個別のロジックに分けて理解していると考える 共通のロジック・基数・生命表・ユニットコストの適用・保険料収入や死亡給付などのキャッシュフローのロジック
個別のロジック・レート計算・商品ごとにアサンプションや給付の定義などが異なる部分
これを表現するために、プログラミングの「継承」の概念を応用する 共通のモデルには共通のロジックを記述する 個々の保険商品のモデルでは差分のみを記述する共通ロジックを追加・上書き(オーバーライド)できる
個々の保険商品を計算するときには、共通のモデルを基に、個々の保険商品のロジックを追加・上書きしてできたモデルが適用される
II-5 生命保険モデルの共通フォーマット
13
深層学習では、ライブラリ共通でモデルを定義できるようなフォーマットが提案されている。(ONNXフォーマットなど)
生命保険モデルにおいても、プロジェクションソフトに依存しない共通フォーマットがあっても良いかもしれない
14
III 生命保険モデルの表現
III-1 計算可能とするための生命保険モデルの表現
15
生命保険モデルを以下のように定義する
生命保険モデルは、 変数の集合である タイムステップを持つ(それぞれの変数で共通)
変数は、 タイムステップを引数とする算式を持つ(算式の計算結果として、タイムステップをインデックスとする1次元配列の値を保持するイメージ)
算式において他の変数を参照することができる。 他の変数を参照する属性として、タイムステップの前・同じ・先を指すか区別する。(backward参照・parallel参照・forward参照ということにする)
III-2 計算可能とするための生命保険モデルの表現(実際)
16
実際には、いくつか修正を必要とする 1次元配列でなく、単一の値がある(予定利率など)これは、すべて同じ値をとる1次元配列として考えることができる
タイムステップが複数ある 例えば、基数計算・レート計算・キャッシュフロー計算でタイムステップは通常異なる
タイムステップが複数ある場合は、タイムステップごとの部分で順に計算していくことができれば問題ない
循環参照があると計算できない。適切な生命保険モデルにおいては、循環参照せずにそれぞれの変数の算式の値を求めることができるとする。
継承については、継承を反映させた生命保険モデルについて考えれば良い。
III-3 仕様書イメージ
17
CIR = 0.025v = 1.0 / (1.0 + CIR)lx = if(x == 0) { 1.0 }
else { lx(x-1) - d_x(x-1) }d_x = lx(x) * qx(x)vx = vx(x-1) * v Dx = lx(x) * vx(x)Cx = d_x(x) * vx(x) * v ^ 0.5Nx = Dx(x) + Nx(x+1) Mx = Cx(x) + Mx(x+1)
基数部分
※一部簡略化しています
III-3 仕様書イメージ
18
// 年払保険料(簡単のため単に12倍としている)grossP = baseP * 12.0// 月払保険料baseP = ( benefit(0) + alpha + annuity_n(0) * gamma )
/ ( (1.0 - beta) * annuity12_m(0) * 12.0 )// 純保険料netP = (benefit(0) + annuity_n(0) * gamma) / annuity_m(0)// 経過t年での給付現価benefit = (Mx(x + t) - Mx(x + n) + Dx(x + n)) / Dx(x + t)// 責任準備金netV = benefit(t) + annuity_n(t) * gamma - annuity_m(t) * netP// 解約返戻金CV = if (t < 10) { max( netV(t) - zill_alpha * (10.0 - t) / 10.0, 0.0) }
else { netV(t) }
レート部分
※一部簡略化しています
III-3 仕様書イメージ
19
// 生命表lx = if (t == 1) { 1.0 }
else { lx(t-1) – d_x(t-1) – dwx(t-1) }lx_pay = if (t <= m) { lx (t) }
else { 0.0 }d_x = if (t == 0) { 0.0 }
else { lx(t) * qx(t) * (1.0 - qwx(t) / 2.0) }dwx = if (t == 0) { 0.0 }
else { lx(t) * qwx(t) * (1.0 - qx(t) / 2.0) }...// キャッシュフロー項目premium_income = lx_pay(t) * grossP * Scommission = premium_income(t) * comm_ratio(t)death_benefit = d_x(t) * S * death_benefit_perS(t)surrender_benefit = dwx(t) * S * surrender_benefit_perS(t)...
キャッシュフロー部分
※一部簡略化しています
20
IV 計算可能とするための技術・概念 (DSL)
IV-1 DSL(ドメイン特化言語)
21
計算可能とするためには、「仕様書」をコンピュータが理解しやすい形に変換する必要がある。これには、DSLに関連する技術が利用できる。
DSLはDomain Specific Language(ドメイン特化言語)の略で、わかりやすく言うと独自のプログラミング言語のこと。
字句解析・構文解析により、コードをコンピュータが理解しやすい抽象構文木という形式に変換する。(一から構文解析器を書かずに、パーサジェネレータのライブラリを利用することができる)
抽象構文木を作成した後に、その解釈や計算処理を行うロジックを記述することで、計算が行える。
IV-2 抽象構文木
22
=
lx ifx
1.0
else
※抽象構文木の説明としては厳密ではない
0-
lx = if(x == 0) { 1.0 }
else{ lx(x-1) - dx(x-1) }
==
処理対象の記述
抽象構文木
lx x-1 dx x-1
IV-3 既存のプログラミング言語では?
23
DSLを開発・管理するのはそれなりに手間なので、既存のプログラミング言語のコードをそのまま仕様書としてしまうという方法も考えられる
しかし、実際に計算させようとすると、計算順序の記述が問題となる。本質的なロジック以外の記述が増え、簡潔さが大きく損なわれる。 forループを記述しなくてはいけないので、記述するコードの量が増える 計算順序を記述しなくてはならず、誤るとエラーとなる 複数商品を管理する場合、それぞれの商品で計算順序が同じ必要がある
24
V 計算可能とするための技術・概念 (グラフ)
V-1 計算順序を指定する問題
25
計算するためには、計算順序を指定する問題を解く必要がある。 変数とその参照関係を有向グラフとして表し、制約を満たすようにソートすれば良い
基数について有向グラフで表すと、下図のようになる(黒矢印:parallel – 同じタイムステップを参照青矢印:backward – 過去のタイムステップを参照赤矢印:forward – 将来のタイムステップを参照)
vx
Nx
qx
MxCx
lx
dx
Dx
V-2 グラフの問題
26
この問題は、以下のグラフに関する問題として解くことができる。(こういう問題に興味を持った人は競技プログラミングで検索!)
問題(配点 500点) 有向グラフがあり、N個のノードとM個の辺を持つ
(N <= 1000, M <= 10000, 多重辺・自己ループも存在しうる) 辺はbackward・parallel・forwardのいずれかの属性を持つ
すべてのノードを1回ずつ使用する、「ループ」のリストを構成して下さい。構成ができない場合はその旨出力して下さい。 ループは、ノードのリストであり、順ループもしくは逆ループの属性を持つ
以下の制約を満たす必要があります。 a->bの辺がある場合、ノードaを含むループよりノードbを含むループが先に来てはいけない 順ループの属性がある場合、そのループのノード間にforwardの属性を持つ辺があってはいけない 逆ループの属性がある場合、そのループのノード間にbackwardの属性を持つ辺があってはいけない ループのノード間で、parallelの属性を持つ辺a->bがある場合、ノードaよりノードbが先に来てはいけない
V-3 トポロジカルソート・強連結成分分解
27
トポロジカルソート 有向グラフの各ノードを順序付けして、どのノードもその出力辺の先のノードより前にくるように並べること
有向グラフのノードをタスク、辺A->BをタスクAができないとタスクBが実行できないという制約に対応させると、トポロジカルソートした順に実行することですべてのタスクを実行することができる。
閉路がある場合はトポロジカルソートはできない
強連結成分分解 有向グラフの強連結成分(=互いに行き来できるノードの集合)ごとのグラフに分解する
強連結成分分解した後は、それぞれの強連結成分を一つのノードとみてトポロジカルソートを行うことができる
V-4 トポロジカルソート(図)
28
fd e
cb
a
g
f
d
e
c
b
a
g
V-5 強連結成分分解(図)
29
fd e
cb
a
g
fd
e
cb
a
g
V-6 グラフの問題の解法
30
1. 強連結成分分解を行うそれぞれの強連結成分がループを表すことになる
2. 強連結成分をノードとしてトポロジカルソートを行うループの順序はこのトポロジカル順となる
3. それぞれの強連結成分において、以下を行う。ここで、辺は強連結成分に含まれるノード間の辺のみを考える backwardとforward属性が両方含まれている場合は、循環するため計算不可 backward属性が含まれている場合は順ループ、forward属性が含まれている場合は逆ループとする。(どちらも無い場合はどちらでも良い)
parallel属性のみを辺としたグラフを作成してトポロジカルソートを行い、ループ内の順序はこのトポロジカル順となるなお、閉路がある場合は循環するため計算不可
V-7 計算順序
31
vx
Nx
qx
MxCx
lx dx
Dx
vx
Nx
qx
MxCx
lx dx
Dx
グラフ
計算順序(青点線四角形:順ループ、赤点線四角形:逆ループ)
V-7 計算順序
32
vx
Nx
qx
MxCx
lx dx
Dx
計算順序(青点線四角形:順ループ、赤点線四角形:逆ループ)
計算順序の説明(タイムステップはxで、0から100までの範囲とします。)1. xが0..100までqxを計算し、xが0..100までvxを計算する2. xが0..100までlx -> dxの順で計算する3. xが0..100までDxを計算する、xが100..0までNxを計算する
(Nxは逆方向から計算する必要がある)4. Cx, MxはDx, Nxと同様