Pythonで国民年金シミュレーション（その２）〜７０歳超も？〜


# Pythonで国民年金シミュレーション（その２）〜７０歳超も？〜

公的年金は3階建ての年金と言われます．1階部分は国民年金です．現役世代は全て国民年金の被保険者となり，高齢期となれば，基礎年金の給付を受けます．
([厚生労働省「公的年金制度の概要」](http://www.mhlw.go.jp/stf/seisakunitsuite/bunya/nenkin/nenkin/zaisei01/index.html))

![pension_1.png](https://qiita-image-store.s3.amazonaws.com/0/193486/55de8fd7-e2cb-f263-b30b-64d7493e1553.png)

2018/1/17日本経済新聞に[「年金受給開始　70歳超も　 政府検討　選択制、額は上乗せ　高齢者に就労促す」](https://www.nikkei.com/article/DGKKZO25752900W8A110C1MM8000/)との記事がありました．

そこで，以前の投稿[Pythonで国民年金をシミュレーションする](https://qiita.com/ryoshi81/items/a312d404e480469d0a22)を少し修正し，Pythonを使った国民年金の保険料の支払いと年金の給付のシミュレーションを70歳超の繰り下げ受給にも対応させてみました．

## 重要：免責事項など
- 本投稿での計算及び計算した数値は仮定のものであり，その数値に一切責任は負いません．
- 本投稿での年金制度の内容は簡略化した説明なので正確な内容は必ず厚生労働省または日本年金機構のHPで確認してください．
- また本内容は2018年1月20日時点のものです．最新の情報は厚生労働省または日本年金機構のHPでご確認ください．
- 本内容は個人の見解であり，所属組織とは一切関係ありません．
- もし誤った記載がありましたら，修正・削除しますので，ご指摘ください．

公的年金の仕組みや支払い・受給額は厚生労働省や日本年金機構のHPで説明されています．

## 準備

今回使用するライブラリをインポートします．


```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
```

## 国民年金の損益分岐点

国民年金の保険料は日本年金機構のHPで調べることができます．
→[日本年金機構「国民年金保険料」](http://www.nenkin.go.jp/service/kokunen/hokenryo/20150313-02.html)

国民年金の受け取りにあたる老齢基礎年金の受給額も同じく日本年金機構のHPで調べることができます．→
[日本年金機構「老齢基礎年金の受給要件・支給開始時期・計算方法」](http://www.nenkin.go.jp/service/jukyu/roureinenkin/jukyu-yoken/20150401-02.html)

HPには「20歳から60歳になるまでの40年間の全期間保険料を納めた方は，65歳から満額の老齢基礎年金が支給されます．」と書かれています．

以下の，Pythonのコードの変数「premium_monthly」と「pension_yearly」に日本年金機構のHPに記載の月額保険料と年金額(年額)を入力すると，20歳から60歳までの保険料の支払い，65歳以降の老齢基礎年金の受け取り，保険料と年金の累積額をシミュレーションすることができます．(保険料，年金額は受給開始年度によって若干変わるので，必ず日本年金機構のHPを確認してください．また，マクロ経済スライドなどによる改定率は今回のシミュレーションでは考慮していません．)


```python
premium_monthly =  # ここに月額保険料を入力
pension_yearly =  # ここに年金額(年額)を入力
revision_rate = 1.0  # 必要に応じて保険料改定率を入力
year = range(20, 100)
cashflow = pd.DataFrame(index=year, columns=['premium','pension'])
cashflow['premium'] = 0
cashflow['premium'] = cashflow['premium'].mask(cashflow.index<60, -premium_monthly*revision_rate*12)
cashflow['pension'] = 0
cashflow['pension'] = cashflow['pension'].mask(cashflow.index>=65, pension_yearly)
cashflow['cashflow'] = cashflow['premium'] + cashflow['pension']
cashflow['accumlation'] = cashflow['cashflow'].cumsum()
```

シミュレーションを可視化します．横軸が年齢，左の縦軸が支払保険料または受け取り年金の毎年の金額，
赤のバーが支払う保険料，青のバーが受け取る老齢年金額，
緑の線が保険料と年金の累積額の推移で，右の縦軸が累積額の金額になっています．


```python
from matplotlib import rcParams
rcParams['font.sans-serif'] = 'Source Han Code JP'
rcParams['font.weight'] = 'regular'
rcParams['axes.titlesize'] = 16
rcParams['ytick.labelsize'] = 14
rcParams['xtick.labelsize'] = 14
plt.style.use('ggplot')
```


```python
fig = plt.figure(figsize=(12, 6))
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()
ax1.bar(cashflow.index, cashflow['pension'], label='年金')
ax1.bar(cashflow.index, cashflow['premium'], label='保険料')
ax1.set_xlabel('年齢')
ax1.set_ylabel('収支')
ax1.set_title('国民年金保険料と老齢基礎年金')
ax1.legend(prop={'size': 15})
ax1.set_ylim(-400000, 800000)
ax2.plot(cashflow.index, cashflow['accumlation'], color='g', label='accumlation')
ax2.set_ylim(-10000000, 20000000)
plt.show()
```

<img width="831" alt="pension_simulation.png" src="https://qiita-image-store.s3.amazonaws.com/0/193486/57f01d01-6fb3-82fc-22f6-0ed76f1d83eb.png">


## 国民年金の繰り上げ受給と繰り下げ受給

老齢基礎年金は，原則として65歳から受け取ることができますが，希望すれば60歳から65歳になるまでの間でも繰り上げて受けることができます．しかし，繰上げ支給の請求をした時点に応じて年金が減額され，その減額率は一生変わりません．([日本年金機構「年金の繰上げ受給」](http://www.nenkin.go.jp/service/jukyu/roureinenkin/kuriage-kurisage/20140421-01.html))

一方，65歳で請求せずに66歳以降70歳までの間で申し出た時から老齢年金を繰下げて請求できます．繰下げ率は，繰下げの請求をした時点に応じて年金額が増額されます．([日本年金機構「年金の繰下げ受給」](http://www.nenkin.go.jp/service/jukyu/roureinenkin/kuriage-kurisage/20140421-02.html))

つまり，国民年金には繰り上げ受給と繰り下げ受給，そして繰り上げ(下げ)を何ヶ月にするかという選択肢があります．

![pension_2.png](https://qiita-image-store.s3.amazonaws.com/0/193486/7a586793-8932-81f2-32e4-d86f8740e16b.png)


2018/1/17日本経済新聞に[「年金受給開始　70歳超も　 政府検討　選択制、額は上乗せ　高齢者に就労促す」](https://www.nikkei.com/article/DGKKZO25752900W8A110C1MM8000/)との記事がありました．

では，何ヶ月の繰り上げ受給，または繰り下げ受給を選択するのが良いのでしょうか．Pythonで60歳から75歳まで（据え置き1パターンと繰り上げ60パターンと繰り下げ60＋60パターン）をシミュレーションして比較してみます．


```python
pension_monthly = pension_yearly // 12
months = range(-60, 121)  # 61から121に修正
age = pd.MultiIndex.from_product([range(60, 100), range(1, 13)], names=['年', '月'])
```

繰り上げ受給の場合と繰り下げ受給の場合の繰り上げ(下げ)月数に応じた受給額月額を計算します．


```python
benefit = pd.Series(pension_monthly, index=months)
benefit = benefit.mask(benefit.index < 0, pension_monthly * (1.0 + 0.005*benefit.index))
benefit = benefit.mask(benefit.index > 0, pension_monthly * (1.0 + 0.007*benefit.index))  # 未定のため仮で0.7％据え置き
#benefit = benefit.mask(benefit.index > 60, pension_monthly * (1.0 + 0.009*benefit.index))  # 仮で他の値に設定する場合
benefit = benefit.round(0)
```

年齢ごとの年金受給額の累積を計算します．上で計算した繰り上げ(下げ)月数ごと受給額を対角化して，pandasのcumsum()を2回使うことで簡単に計算できます．


```python
benefit = pd.DataFrame(np.diag(benefit.values), index=age[:len(months)], columns=months)
benefit = pd.DataFrame(index=age).merge(benefit, how='left', left_index=True, right_index=True).fillna(0)
pension = benefit.cumsum().cumsum()
```

各年齢ごとに最も受給額の大きい選択肢（繰り上げか繰り下げか）を調べます．


```python
pension['最大受給額'] = pension.max(axis=1)
pension['最良繰り下げ月数'] = pension.idxmax(axis=1)
pension
```

CSVに書き出します．


```python
pension.to_csv('pension_simulation.csv')
```

Excelに書き出す場合はこちら．


```python
writer = pd.ExcelWriter('pension_simulation.xlsx', engine='xlsxwriter')
pension.to_excel(writer, sheet_name='国民年金シミュレーション')
# フォーマットを整える
workbook  = writer.book
worksheet = writer.sheets['国民年金シミュレーション']
header_format = workbook.add_format({
    'bold': True,
    'text_wrap': True,
    'fg_color': '#D7E4BC',
    'border': 1})
index_format = workbook.add_format({
    'bold': True,
    'valign': 'top',
    'fg_color': '#FFCC99',
    'border': 1})
values_format = workbook.add_format({
    'border': 1})
result_format = workbook.add_format({
    'fg_color': '#FFFFCC',
    'border': 1})
for col_num, value in enumerate(list(pension.index.names)+list(pension.columns)):
    worksheet.write(0, col_num, value, header_format)
from itertools import product
for row_num, (y_val, m_val) in enumerate(product(pension.index.levels[0], pension.index.levels[1])):
    worksheet.write(row_num+1, 0, y_val, index_format)
    worksheet.write(row_num+1, 1, m_val, index_format)
for row_num, _row_val in enumerate(pension.index):
    for col_num, _col_val in enumerate(pension.columns):
        worksheet.write(row_num+1, col_num+2, 
                        pension.iloc[row_num, col_num], values_format)
for row_num, (_y_val, _m_val) in enumerate(pension.index):
    worksheet.write(row_num+1, pension.shape[1]+len(pension.index.names)-2,
                    pension.iloc[row_num, -2], result_format)
    worksheet.write(row_num+1, pension.shape[1]+len(pension.index.names)-1, 
                    pension.iloc[row_num, -1], result_format)
# Excelファイルを保存
writer.save()
```

出力した表の見方を説明します．
1列目が年齢，2列目が何歳何ヶ月かを表しています．
1行目は60ヶ月の繰り上げ受給(-60)から120ヶ月(現時点では60まで可)の繰り上げ受給(120)を表しています．
各セルは，1行目の繰り上げ(下げ)月数を選択した場合の，1,2列目の年齢(と何ヶ月か)のときの累積年金受給額です．
右から2番目の列は各行の最大の累積年金受給額です．
一番右の列はその最大累積受給額を実現する繰り上げ(下げ)月数を表しており，もしその年齢が寿命だった場合に最もよい選択肢となります．

もし平均寿命まで長生きできると何ヶ月の繰り上げ(下げ)受給がよいのでしょうか．以下を参考に出力テーブルでぜひ調べてみてください．

- [日本経済新聞2017年7月27日付記事「平均寿命、男女とも過去最高更新　女性87.14歳 男性80.98歳」](https://www.nikkei.com/article/DGXLASDG26HGD_X20C17A7000000/)
- [厚生労働省「主な年齢の平均余命」](http://www.mhlw.go.jp/toukei/saikin/hw/life/life10/01.html)

仮に75歳まで繰り下げ可能になった場合，平均寿命を基準に考えても，繰り下げが70歳までと比べ，どの程度繰り下げるかの選択は悩ましい問題になります．
一方で，人生100年時代と言われますが，100歳まで長生きできると60ヶ月の繰り上げ受給と60ヶ月(あるいは，120ヶ月)の繰り下げ受給とではかなりの差が出ることには変わりありません．

## 最後に

- 累積年金受給額が最大になる繰り上げ・繰り下げ月数は基本的には寿命で決まります．
- 国民年金はある程度シミュレーションできます．

そもそも年金は長生きリスクに備えるためのものです．また，年金などの資産設計は自己責任です．自分の資産の管理にPythonを役立ててみてください．

＊本内容について，もし誤った記載がありましたら，修正・削除しますので，ご指摘ください．

## 参考

- [Pythonで国民年金をシミュレーションする](https://qiita.com/ryoshi81/items/a312d404e480469d0a22)
- [厚生労働省「公的年金制度の概要」](http://www.mhlw.go.jp/stf/seisakunitsuite/bunya/nenkin/nenkin/zaisei01/index.html)
- [日本年金機構](http://www.nenkin.go.jp/index.html)
- [日本経済新聞2018/1/17付記事「年金受給開始　70歳超も　 政府検討　選択制、額は上乗せ　高齢者に就労促す」](https://www.nikkei.com/article/DGKKZO25752900W8A110C1MM8000/)