0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

アクチュアリーのためのPython入門(利源分析)

0
Last updated at Posted at 2026-03-15

アクチュアリーのためのPython入門(第17回)

保険収支に死差損益を追加する

📚 アクチュアリーのためのPython入門
この記事は入門編の一部です。
目次はこちら

はじめに

前回は、定期保険を例に、
死亡率や解約率を動かすことによって、
保険収支がどう変化するのか確認しました。

今回は、そこに利源分析のうち死差損益を加えて、
その変化も確認できるようにします。

利源分析については
アクチュアリー会の一次試験では試験範囲外ですが、
生命保険数学のテキストに記載がありますのでご参照ください。

今回すること

今回は、少しだけ保険数理の説明を加えます。
前回までの保険収支に次の要素を加えます。

  • 予定事業費
    保険料に含まれる事業費の目安です。
    ここでは、営業保険料 - 純保険料で計算しておきます。
  • 解約契約の消滅時保険料積立金
    解約となった契約の保険料積立金です。
  • 費差損益
    予定事業費 - 事業費で計算します。
  • 死差損益
    保険料収入 + 予定利息 - 予定事業費 - 保険料積立金繰入
     - 保険金支払 - 解約契約の消滅時保険料積立金で計算します。

なお、利息収入 = 予定利息の前提で計算していますので、
利差損益は0と仮定します。

費差損益と死差損益

コードは前回までと基本的に同じです。
次の変数を加えておきます。
expected_expenses_total : 予定事業費の合計
expenses_profit_total : 費差損益の合計
surrender_reserve_total : 解約契約の消滅時保険料積立金の合計
mortality_profit_total : 死差損益の合計

term.py
# 保険収支
# アサンプションの設定
c_period = 10  # 計算する期間
k = (0.5, 0.7, 1.1)        # 死亡指数
qwx = [0.02] * c_period    # 解約率

# 契約内容
contracts = [
    {"sex":"M", "age":20, "term":10, "amount":10_000_000},
    {"sex":"F", "age":20, "term":10, "amount":10_500_000},
    {"sex":"M", "age":30, "term":10, "amount":20_000_000},
    {"sex":"F", "age":30, "term":10, "amount":20_500_000},
    {"sex":"M", "age":40, "term":10, "amount":30_000_000},
    {"sex":"F", "age":40, "term":10, "amount":30_500_000},
    {"sex":"M", "age":20, "term":20, "amount":10_500_000},
    {"sex":"F", "age":20, "term":20, "amount":10_000_000},
    {"sex":"M", "age":30, "term":20, "amount":20_500_000},
    {"sex":"F", "age":30, "term":20, "amount":20_000_000},
    {"sex":"M", "age":40, "term":20, "amount":30_500_000},
    {"sex":"F", "age":40, "term":20, "amount":30_000_000},
    {"sex":"M", "age":20, "term":30, "amount":20_000_000},
    {"sex":"F", "age":20, "term":30, "amount":30_000_000},
    {"sex":"M", "age":30, "term":30, "amount":40_000_000},
    {"sex":"F", "age":30, "term":30, "amount":20_000_000},
    {"sex":"M", "age":40, "term":30, "amount":30_000_000},
    {"sex":"F", "age":40, "term":30, "amount":10_500_000}
]

inprem_total = {}    # 保険料収入の合計
interest_total = {}  # 利息収入の合計
benefit_total = {}   # 保険金支払の合計
surrender_total = {} # 解約返戻金の合計
expenses_total = {}  # 事業費の合計
reserve_total = {}   # 保険料積立金繰入の合計
profit_total = {}    # 利益の合計

expected_expenses_total = {} # 予定事業費の合計
expenses_profit_total = {}   # 費差損益の合計
surrender_reserve_total = {} # 解約契約の消滅時保険料積立金の合計
mortality_profit_total = {}  # 死差損益の合計

収支に使う変数に加えて、
先ほどの費差損益、死差損益に使う変数も初期値を0としておきます。

term.py
for scale in k:
# 保険収支の合計の初期値
    inprem_total[scale] = [0] * c_period    # 保険料収入
    interest_total[scale] = [0] * c_period  # 利息収入
    benefit_total[scale] = [0] * c_period   # 保険金支払い
    surrender_total[scale] = [0] * c_period # 解約返戻金支払い
    expenses_total[scale] = [0] * c_period  # 事業費
    reserve_total[scale] = [0] * c_period   # 保険料積立金繰入
    profit_total[scale] = [0] * c_period    # 利益

    expected_expenses_total[scale] = [0] * c_period # 予定事業費
    expenses_profit_total[scale] = [0] * c_period   # 費差損益
    surrender_reserve_total[scale] = [0] * c_period # 消滅時保険料積立金
    mortality_profit_total[scale] = [0] * c_period  # 死差損益

保険収支に変更は加えていません。
次は前回と同じです。

term.py
    # 保険収支の計算
    for c in contracts:
        sex = c["sex"]   # 性別
        age = c["age"]   # 加入年齢
        term = c["term"] # 保険期間
        l0 =c["amount"]  # 初期保険金額

        # 残存表の作成
        lx = [l0]        # 保有保険金額
        dx = []          # 死亡保険金額
        wx = []          # 解約保険金額
        # 生命表の作成
        for t in range(c_period):
            q = qx[sex][age + t]
            w = qwx[t]
            next_d = lx[-1] * q * scale 
            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)

        # 保険収支の項目
        inprem = []    # 保険料収入
        interest =[]   # 利息収入
        benefit = []   # 保険金支払い
        surrender = [] # 解約返戻金支払い
        expenses = []  # 事業費
        reserve = []   # 保険料積立金繰入
        profit = []    # 利益

        P = float(PremT(sex, age, term))
        # 保険収支の計算
        for t in range(0, c_period):
            if t < term:
                inprem.append(lx[t] * P)    # 保険料の収入
                Vt = float(ResT(sex, age, term, t)) # 期始保険料積立金
                Vt1 = float(ResT(sex, age, term, t + 1)) # 期末保険料積立金
                interest.append((lx[t + 1] * Vt1 + lx[t] * Vt) * 0.006 / (2 + 0.006)) # ハーディの公式
                benefit.append(dx[t])       # 死亡保険金の支払い
                W = float(SVT(sex, age, term, t + 1))
                surrender.append(wx[t] * W)   # 解約返戻金の支払い
                expenses.append(inprem[t] * 0.4)  # 事業費の支払い
                # 保険料積立金繰入
                if t == 0:
                    reserve.append(lx[1] * Vt1)
                else:
                    reserve.append(lx[t + 1] * Vt1 - lx[t] * Vt)
                # 保険収支の計算
                profit.append(inprem[t] - benefit[t] - surrender[t] - expenses[t] - reserve[t])

            # 満期後は0を入力
            else:
                inprem.append(0)
                benefit.append(0)
                surrender.append(0)
                expenses.append(0)
                reserve.append(0)
                profit.append(0)

            inprem_total[scale][t] += inprem[t]       # 保険料収入の合計
            benefit_total[scale][t] += benefit[t]     # 保険金支払いの合計
            surrender_total[scale][t] += surrender[t] # 解約返戻金支払いの合計
            expenses_total[scale][t] += expenses[t]   # 事業費の合計
            reserve_total[scale][t] += reserve[t]     # 保険料積立金繰入の合計
            profit_total[scale][t] += profit[t]       # 保険収支の合計

ここから利源分析部分を加えます。
まず、各年度の費差損益、死差損益で必要になる変数を定義します。
ここはまだfor scale in k:およびfor c in contracts:の中です。
その後、for文で計算期間内の計算を行います。
それぞれの計算を行い、保険期間外の場合は0で埋めます。

term.py
        # 利源分析
        expected_expenses = []  # 予定事業費
        expenses_profit = []    # 費差損益
        expected_interest = []  # 予定利息
        surrender_reserve = []  # 解約時保険料積立金
        mortality_profit = []   # 死差損益

        for t in range(0, c_period):
            if t < term:
                # 費差損益の計算
                P = float(PremT(sex, age, term))
                nP = float(netPremT(sex, age, term))
                expected_expenses.append(lx[t] * (P - nP)) # 予定事業費
                expenses_profit.append(expected_expenses[t] - expenses[t]) # 費差損益
                # 死差損益の計算
                surrender_reserve.append(wx[t] * Vt1) # 消滅時保険料積立金
                value = inprem[t] + interest[t] - expected_expenses[t] - reserve[t] \
                      - benefit[t] - surrender_reserve[t] 
                mortality_profit.append(value) # 死差損益
            else:
                expected_expenses.append(0)
                expenses_profit.append(0)
                surrender_reserve.append(0)
                mortality_profit.append(0)

最後に、合計値を計算します。
基本的に保険収支の流れと同じですので、
ここまで理解できていれば、難しくないと思います。

term.py
            expected_expenses_total[scale][t] += expected_expenses[t]
            expenses_profit_total[scale][t] += expenses_profit[t]
            expected_interest_total[scale][t] += expected_interest[t]
            surrender_reserve_total[scale][t] += surrender_reserve[t]
            mortality_profit_total[scale][t] += mortality_profit[t]

最後に結果を確認します。

term.py
for index in k:
    print("mortality_index","t","expected_expenses","expenses","expenses_profit","inPrem",\
          "expected_interest","expected_expenses","reserve","benefit","surrender_reserve","mortality_profit")
    for t in range(0, c_period):
        print(index, t, int(expected_expenses_total[index][t]),
            int(expenses_total[index][t]),
            int(expenses_profit_total[index][t]),
            int(inprem_total[index][t]),
            int(expected_interest_total[index][t]),
            int(expected_expenses_total[index][t]),
            int(reserve_total[index][t]),
            int(benefit_total[index][t]),
            int(surrender_reserve_total[index][t]),
            int(mortality_profit_total[index][t]),)

数値がたくさんで見にくいですが、
死亡指数が1を超えた場合は死差損となっているのが確認できます。

mortality_index t expected_expenses expenses expenses_profit inPrem expected_interest expected_expenses reserve benefit surrender_reserve mortality_profit
0.5 0 636736 538294 98442 1345735 1195 636736 399674 152325 60618 97575
0.5 1 623767 527308 96458 1318272 3489 623767 367295 158812 59378 112507
0.5 2 611047 516532 94514 1291332 5590 611047 335170 165445 58162 127096
0.5 3 598571 505962 92609 1264905 7503 598571 304243 171851 56969 140771
0.5 4 586335 495592 90742 1238981 9228 586335 272579 179046 55798 154450
0.5 5 574332 485418 88913 1213546 10759 574332 239321 187373 54650 168629
0.5 6 562555 475435 87120 1188587 12074 562555 200270 199047 53522 185265
0.5 7 550996 465632 85364 1164081 13146 550996 158169 212632 52414 203014
0.5 8 539647 456004 83643 1140011 13959 539647 113598 227943 51326 221453
0.5 9 528501 446545 81956 1116363 14508 528501 69979 243192 50257 238941
mortality_index t expected_expenses expenses expenses_profit inPrem expected_interest expected_expenses reserve benefit surrender_reserve mortality_profit
0.7 0 636736 538294 98442 1345735 1195 636736 399600 213255 60618 36719
0.7 1 623673 527221 96452 1318052 3488 623673 367075 222298 59368 49125
0.7 2 610857 516355 94502 1290887 5587 610857 334808 231538 58140 61129
0.7 3 598283 505691 92592 1264229 7497 598283 303744 240454 56935 72308
0.7 4 585947 495227 90719 1238069 9219 585947 271949 250466 55753 83172
0.7 5 573841 484956 88884 1212392 10746 573841 238568 262053 54592 94082
0.7 6 561960 474872 87087 1187181 12056 561960 199406 278307 53452 106111
0.7 7 550290 464964 85325 1162411 13123 550290 157212 297215 52331 118484
0.7 8 538824 455224 83599 1138061 13930 538824 112574 318517 51229 130846
0.7 9 527554 445646 81907 1114115 14472 527554 68918 339707 50144 142263
mortality_index t expected_expenses expenses expenses_profit inPrem expected_interest expected_expenses reserve benefit surrender_reserve mortality_profit
1.1 0 636736 538294 98442 1345735 1194 636736 399453 335115 60618 -84993
1.1 1 623486 527045 96440 1317614 3486 623486 366635 349202 59346 -77570
1.1 2 610478 515999 94479 1289999 5582 610478 334084 363579 58096 -70658
1.1 3 597708 505151 92557 1262879 7486 597708 302747 377426 56868 -64384
1.1 4 585172 494499 90673 1236247 9201 585172 270692 392967 55662 -59045
1.1 5 572862 484034 88828 1210086 10720 572862 237068 410949 54477 -54551
1.1 6 560770 473750 87020 1184375 12021 560770 197686 436213 53311 -51586
1.1 7 548880 463631 85248 1159078 13076 548880 155308 465582 52164 -49780
1.1 8 537181 453668 83513 1134172 13872 537181 110537 498634 51034 -49344
1.1 9 525665 443854 81811 1109635 14402 525665 66812 531439 49919 -49798

まとめ

今回までで、複数契約の保険収支に加え、
感応度分析と利源分析を行いました。

新契約のみですが、商品開発で、
試算をする際に行う基本的な、

  • 保険料の計算
  • 保険料積立金の計算
  • 解約返戻金の計算
  • 保険収支
  • 感応度分析と利源分析

ができました。

直近の2回では、Pythonのレベルが上がっていませんので、
入門編で取り上げる保険数理の難度はこれくらいまでにして、
今後以降でPythonの効率化をはかっていきたいと思います。

次回は一般のPython入門でもよく取り上げられるpandasを使います。

前の記事
感応度分析

次の記事
pandasを使ったExcelとの連携

📚 目次
アクチュアリーのためのPython入門

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?