LoginSignup
10
7

More than 5 years have passed since last update.

たかしくん (with TensorFlow) と考える積立年金の利率

Last updated at Posted at 2018-05-03

最近機械学習抜きに TensorFlow を触ったので紹介します。
TensorFlow で方程式の近似解を求めたい人の参考になれば幸いです。

  • (2018/05/07) 平均預け入れ年数を修正

最初に

  • この記事内の人物・会社はフィクションです
  • TensorFlow を使いますが、Deep Learning どころか Neural Network も出てきません
    • あくまで高次方程式の近似解を求めるために使います
  • 定式化のため問題の一部を簡単化してます
  • Google Colaboratory で動かしました(Chrome 以外だと上手く表示されないかも)
  • 本エントリ内の画像は かわいいフリー素材集 いらすとや 様より拝借しております

導入

たかしくんは 現在 26歳 の Software Engineer です。

kaisya_man_bad.png

ある日、とある青い銀行に勤めるお友達(広義)からこんなお誘いがありました。

job_ginkouin.png

「たかしくん!僕と契約して個人積立年金を始めてよ!(=ノルマのための数字になってよ)」

お友達からのお誘いだったので、たかしくんは詳しくお話を聞くことにしました。

聞いてみたところ以下のことが分かりました。

  • 毎月 20,000 円 支払う
    • 今は 1月とし、もし加入したら今月から支払うとする
    • 1年間で 240,000 円支払う
  • 65歳 になるまで支払いを続ける(65 - 26 = 39 年間支払いを続ける)
  • 65歳になったらすぐもらえる(据え置き期間はなし)
  • 9,930,000 円をまとめてもらえる
    • 期間を挟みつつ分割払い、ではない

たかしくんはこれがお得(年利が高い)なら始めてみようと思いました。
ですがその場で年利を計算できなかったため、持ち帰り案件とすることにしました。

shinsyakaijin_run_man2.png

問題の定式化

年利が高いとは(たかしくんが個人積立年金を始める基準)

年利が高いか否かを判断するために、たかしくんは定期預金の年利と比較してみることにしました。

【定期預金の金利を徹底比較!】定期預金金利の高さで選ぶ!おすすめネット銀行ランキング!|ネット銀行比較|ザイ・オンライン

上記のサイトを確認したところ、一番高い銀行では 5年 預けると 0.30% の年利がつくことがわかりました(2018年5月3日時点)。

たかしくんが今から個人積立年金を始めた場合、39年間支払います(上記参照)。
払った年によって預け入れる年数が変わりますが、平均すると (39 + 1) / 2 = 20 年お金を預け入れることになります($ (\sum_{k=1}^N k) / N = (N + 1)/ 2$ より)。

ですので上記の 5年 の定期預金の年利と比較した結果、
たかしくんは 個人積立年金の年利0.35% 以上 なら始めようと決意しました。

年利と総受け取り額の関係

ここで年利と総受け取り額の関係を表すため、下記のようなパラメータを定義します。

パラメータ 内訳
$R$ [%] 個人積立年金の年利
$P$ [円] 毎年たかしくんが支払う金額
$N$ [年] たかしくんが支払いを続ける期間
$S(N)$ [円] たかしくんが $N$ 年間支払った後にもらえる金額

ここで、下記のような $r$ を定義します。

$$
r = 1 + \frac{R}{100}
$$

仮定

ここで少し面倒なのが、年利は 1年間 お金を預けた場合に発生するのに対し、たかしくんは 毎月 積立金を支払っているということです。

例えば、たかしくんが 2018年5月 に支払った $p$ 円は、2019年5月 になって初めて $rp$ 円になるということです。

ここでは計算を簡単にするため、以下の仮定を置きます。
(一ヶ月単位の利率を仮定することでより正確に計算できますが、それは各自でやってみてください)

  • 仮定:たかしくんはその年の最後に $P$ 円をまとめて払ったとして、その 1年後に $r$ 倍になる

1年支払った場合の総受取金額

その年の最後に $P$ 円払ったとして、そのお金に年利がかかる前に返金されるので、下記のようになります。

$$
S(1) = P
$$

2年支払った場合の総受取金額

最初の年に支払った金額には年利がついて、2年目に支払った金額には年利がついてないです。

$$
S(2) = P\cdot r + P
$$

N 年支払った場合の総受取金額

\begin{align}
S(N) &= P \cdot r^{N-1} + P \cdot r^{N-2} + ... + P \cdot r + P\\
&= P \cdot \frac{r^N - 1}{r - 1}
\end{align}

年利を求めるには

ここで実際に求めたい(わかっていない)パラメータは $r$ のみです。
他のパラメータはわかっているので実際に代入してみます。

9930000 = 240000 \cdot \frac{r^{39} - 1}{r - 1}

分かりやすいよう両辺を $240000$ で割ります。

\frac{993}{24} = \frac{r^{39} - 1}{r - 1}

あとは上記の式を満たす $r$ を求めるだけです。

ですがたかしくんは精々2次方程式の解法しか覚えていません。

また、勾配法などでこの方程式の近似解を求めようにも、
たかしくんは微分が大の苦手なので上記の式を $r$ について微分することができません。

困ったことにこのままでは $r$ を求めることができません。

komatta_man2.png

TensorFlow による近似解の計算

しかしたかしくんはただのたかしくんではありません。
闇のパワー(TensorFlow)を持った "たかしくん with TensorFlow" なのです。

kids_chuunibyou_boy.png

そこでたかしくんは TensorFlow を使って利率の近似解を求めることにしました。
(近似解はダメ?厳密解じゃないと許さない?そんなやつは理想を抱いて溺死しろ

コード(TensorFlow)

LEARNING_RATE(学習率)の値によっては収束しなかったり、収束が遅いです。

積立年金.py
import numpy as np
import tensorflow as tf

AGE_START = 26              # 支払い開始年齢
AGE_END = 65                # 支払い終了年齢
YEAR = AGE_END - AGE_START  # 支払い期間
COST_MONTH = 20000          # 月に支払う額
COST_YEAR = COST_MONTH * 12 # 年間支払い額
PENSION_TOTAL = 9930000     # 最終的にもらえる額(発表されてる額)
R_INIT = 2.                 # 年利の初期値(%)
EPOCH = 50                  # エポック数(パラメータの更新回数)
LEARNING_RATE = 0.000001    # 学習率、0.01 とかだとすぐ nan になって収束しないので注意

# Model parameters
r =  tf.Variable([1. + R_INIT/ 100], dtype=tf.float32)

# Model
model = (tf.pow(r, YEAR) - 1) / (r - 1)

# Label
label = tf.constant([PENSION_TOTAL / COST_YEAR], dtype=tf.float32)

# loss
loss = tf.square(model - label)

# optimizer
optimizer = tf.train.GradientDescentOptimizer(LEARNING_RATE)
train = optimizer.minimize(loss)

# 初期化用
init = tf.global_variables_initializer()

with tf.Session() as sess:
    init.run()
    print("           init r[%]: ", R_INIT)
    # EPOCH 回パラメータ更新
    for epoch in range(EPOCH):
        sess.run(train)
        # print(sess.run(r))
    r_estimated = (sess.run(r)[0] - 1.) * 100
    pension = sess.run(model)[0] * COST_YEAR
    pension = int(pension)
    print("      estimated r[%]: ", r_estimated)
    print("estimated pension[¥]: ", pension)
    print("             diff[¥]: ", PENSION_TOTAL - pension)
実行結果
           init r[%]:  2.0
      estimated r[%]:  0.3084421157836914
estimated pension[¥]:  9929992
             diff[¥]:  8

上記の結果から、年利は約 $0.308$ % であり、この場合の誤差は $8$ 円であることがわかりました。
993 万円中の 8 円ですので、許しても良いのではないでしょうか。
(許せない人は、コード内の dtype=tf.float32dtype=tf.float64 にしてみましょう)

よって年利が $0.308$ %、すなわち $0.35$ % 未満であることが判明したので、
たかしくんは今回は個人積立年金を 始めない ことにしました。

結論

  • 個人積立年金するぐらいなら定期預金(5年)で十分

最後に

今回の例では色々仮定をおいたり、メリット・デメリットを無視したので、実際はそんなに簡単には決められないかもですが、このような考え方もあると知ってもらえれば幸いです。

ちなみに私は今年の昇給額がしょっぱかったのでまだ始めません。

そしてこれからは Qiita ポエマーとして稼いでいこうと思います。

10
7
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
10
7