gggggraziegrazie

graizegrazieさんのやったこと、学んだことを記録する雑記帳です

厚生年金について調べてみた

 厚生年金という言葉は知っているものの、制度について全然理解していないことに最近気づきました。今回は厚生年金について調べた結果を纏めます。ただし、会社勤めをしている1980年以降生まれの方を対象として記載したので、一部省略した記述となっています。自分のケースは下記を参考にご自身で調べていただければと思います。

厚生年金とは

 厚生年金とは、公的年金の1つです。公的年金の1つである国民年金は誰でも加入できるのに対し、厚生年金は会社勤めをする人しか加入することが出来ません(*1)。

厚生年金の納付額

 厚生年金加入者は、国民年金と厚生年金の両年金分を納付する必要があります。納付する額は、

  1. 毎年4月~6月の間の報酬(基本給+各種手当)の平均
  2. 国の定める標準報酬月額表[1]
  3. その時の保険料率

から算出されます。

 例えば平成26年9月分からの保険料額表を見ると、1.の平均報酬額が30万だと、標準報酬月額表では18等級になります。この時の保険料率は17.474%であることから、保険料は月額約5.24万円とわかります。ただし厚生年金は、会社と個人が50%:50%の折半で保険料を納付します。そのため上記例では、個人で納付する額は月額約2.62万円となります。

 この額は同年9月~次年の8月まで適用されます。ただし、7月以降に平均報酬が4~6月の平均報酬から大きく変化した場合、適宜保険料は改定される模様です[2]。

 なお、厚生年金受給資格に満たない人は、個人での任意加入も可能です。

休職中の取り扱い

 出産前後休業や育児休業中は、会社分・本人分の両方が免除となります(育児休業については子供が3歳になるまで)[3]。その他休業中の厚生年金料負担は、会社の決まり次第で変化する模様です(本人はその時納めないにしても、会社が負担してくれたり、会社が一時的に肩代わりして別途支払いするときがあります)[2]。

厚生年金の受給額

 年金機構のサイト[4]を見ると、

   年金額 = 定額部分(1)+報酬比例部分(2)+加給年金額(3)

   (1)1,626円 × 定額部分の単価[5] × 被保険者期間の月数
(2)平均標準報酬月額(*2) × 報酬比例部分の乗率[5] × 被保険者期間の月数
(3)厚生年金保険の被保険者期間が、20年以上または40歳(女性は35歳)以降15年の人で、定額部分支給開始年齢に達した時点で、その人に生計を維持されている対象者がいる場合に支給[4]。
(*2)被保険者期間の各月の標準報酬月額と標準賞与額の総額を、被保険者期間の月数で除して得た額。

として算出されます。

 例えば昭和59年9月8日に生まれた人が下記の条件を満たす時、

  • 定額部分の単価 : 1.000([4]より)
  • 報酬比例部分の乗率 : 5.481([4]より)
  • 厚生年金加入期間 : 40年 = 40×12 = 480月
  • 平均標準報酬月額 : 70万(生涯平均年収840万)
  • 加給年金の対象となる家族はいない

   年金額 = (1,626×1.000×480) + (70×5.481×480) + 0
= (780,480) + (184,162)
       = 964,642(月額約8万円)
となります。
 うーん。厚生年金だけの額とはいえ、少ない気がしますねぇ。。。

特異値分解(SVD)の概要

 データの開先手法の1つとして、特異値分解(SVD:Singular Value Decomposition)という手法があります。SVDでは、不要なデータを取り除くことができるため、画像やテキストデータの圧縮や解析に使われます[1][2]。以降では数式を用いてSVDについて概要を説明します。
 

特異値とは

 そもそも特異値とは、ある行列とその行列の随伴行列(ある行列の共役かつ転置した行列)の積の固有値の非負な平方根のことです。
#直感的にわかる説明ができずすいません。そのレベルまでは理解できてないです。。

特異値分解(SVD)の数式表現

 SVDは行列とベクトルを使った2種類の表し方があります。まず最初に行列を使って表現してみます。例として、AというI×J行列のSVDを行うと、
{ \displaystyle
 A = UDV^{*}
}
と分解できます。ここで、

  •  U : IK列のユニタリ行列
  •  D : KK列の対角行列(対角成分は特異値 \alpha_{k}, k\in{1,2,...,K}で、 \alpha_{1} \geq \alpha_{2} \geq ... \geq \alpha_{K}を満たす)
  •  V^{*} : IK列のユニタリ行列の随伴行列

とします。このとき、Kとは、行列 Aのランクを指します(K  \leq I, J)。

次にベクトルを使って表現すると、
{ \displaystyle
 A = \sum_{k=1}^{K}\alpha_{k}u_{k}v_{k}^{T}
}
とできます。ここで、

  •  u_{k} : 左特異ベクトル(上記 Uのk行成分
  •  \alpha_{k} : 特異値
  •  v_{k} : 右特異ベクトル(上記 V^{*}のk列成分

とします。

 上記のように、SVDを使うことで対象となる行列 Aを、行列 AのランクKまでサイズを縮小、つまりデータサイズを圧縮してデータを表現できます。

SVDによる擬似近似

 特異値の値に閾値を設けることで、SVDでは擬似的にランクを落とすことが可能です。この操作により、サイズをKK'(K  \in K')に落とすことができます(計算式は[3]の1.4節を参照)。

ROSでパラメータを登録する方法

 ロボット業界でよく使われるフレームワークとして、ROS[1]というものがあります。ROSでは、生成するプロセス(ROS的にはノード)毎にパラメータを設定することが出来ます。先日そのパラメータを使う機会がありましたので、パラメータの設定方法を書きます。なおプログラミング言語を用いて説明する部分に関しては、Pythonを使って記述します。

パラメータとは

 パラメータとは、ノードが外部に公開する変数のことです。外部からパラメータに値を設定することで、ノードの挙動を変更することが出来ます。例えば移動を司るノードが外部にパラメータとして速度を公開している時、外部からパラメータを操作することで速度を変更することができます。

パラメータの設定方法

 パラメータを設定する方法には
  1. ソース上で設定
  2. ノード起動時に設定する
  3. コマンドラインで設定する
 の3パターンがあります。それぞれの設定方法により、同じプログラムを使っても生成されるノード毎に保有するパラメータが異なるので注意が必要になります。また上記3つの方法があることで、ROSではいつでもノードにパラメータを設定することができるとわかります。

ソース上で設定する

 ソースコードで設定するには、set_param関数を使います。ソースコード上で設定することで、そのソースを元に作られたノードには必ずパラメータが設定された状態で生成されます。つまり、

 rospy.set_param('foo', 0.1) # デフォルト値0.1

とすれば、ノードは起動時点で必ずデフォルトで0.1という値が入ったfooというパラメータを持つことになります。

ノード起動時に設定する

 ノードを起動する時、パラメータを設定して起動することができます。方法としては、

 ./foo.py /foo/bar:=0.1

とすることで、ノードfooに0.1という値を持つ変数barを持たすことができます。
 起動時にパラメータを設けることで、同じプログラムから生成するノードで別々のパラメータを設けることができます。また、プログラムを修正するせずにパラメータを設定することで、お試しでパラメータを使って、ノードの動きを検証してみるということができます。

コマンドラインで設定する

 コマンドラインでパラメータを設定するにはrosparamを使います。使い方としては、

 rosparam set /foo/bar 0.1

コマンドラインで実行します。
 今まではノードを起動するまでの段階でパラメータを設定していましたが、この方法を使うことで起動後でもパラメータを設定することができます。

[1]ROS.org | Powering the world's robots

area/district/region/zoneの使い分け

 英単語の勉強をしていた時、"district"という単語が"地区"という意味を知りました。その時、「あれ?areaと似たような意味だけど、使い分けはどうすればいいのだろう?」と思いました。そのため、地区とか地域という意味の単語(area, district, region, zone)はどの様な使い分けがあるのかを英英辞典longmanで調べてみたので、纏めます。

 英英辞典で調べてみた結果、各単語の使い分けをする時に意識するのは、範囲の大小ではなく区切り方でした。それぞれの単語の意味は

area 特定の地域
district 公的に定められた地域
region 広大な地域(明確に定義できるかは関係なし)
zone 何か特徴を持った地域

ということが分かりました。

英英辞典で意味を調べてみた結果

 英英辞典で単語の意味と例文を調べて見た結果、下記の表の通りになりました。

単語 意味
area a particular part of a country, town etc Crime rates are significantly higher in urban areas.
district an area of a country, city etc that has official borders a house in a pleasant suburban district.
region a large area of a country or of the world, usually without exact limits Flooding is likely in some coastal regions of the Northeast during the early part of the week.
zone a large area that is different from other areas around it in some way San Francisco and Tokyo are both located in earthquake zones.

habitとcustomの使い分け

 学校で習う英単語の中に、「習慣」という意味で習う単語が"habit"と"custom"の2つあります。全く同じ意味という訳はないと感じつつ、今までその違いを調べたことはありませんでした。今回久々に気になったので、両者の違いを調べてみました。その結果、2つの単語は「習慣」という意味はあるものの、用途が全く異なる単語であることがわかりました。

 英英辞典Longmanでそれぞれの単語の意味を調べてみたところ、"habit"は「習慣」で"custom"は「風習」と訳すのが正しいという結果です。下記にLongmanに記載されている意味と例文を記載します。

  • habit

"something that you do regularly or usually, often without thinking about it because you have done it so many times before."
Ex. Regular exercise is a good habit for kids to develop.

  • custom

"something that is done by people in a particular society because it is traditional."
Ex. It's the custom for the bride's father to pay for the wedding.

C/C++で配列の初期化に#includeを使う

 データファイルを取り扱う時、そのデータを読んで配列に格納していくのは面倒ですよね。実は、配列の初期化には#includeプリプロセッサが使えます。今回は#includeを使って配列を初期化した時の挙動について書きます。

 なお今回のテスト環境は、

で、includeするファイルはソリューションファイルと同じディレクトリに存在するものとします。

使用コード・ファイル

 今回の実験には、#includeで初期化した配列をprintfで各要素を表示するソースコードと、4つの数字","で区切られたデータファイルを使いました。それぞれの内容は下記の通りです。

ソースコード

#include "stdio.h"

int sample[] = 
{
#include "sample.txt"
};

int main(void)
{
 unsigned int i;
 unsigned int buf_size;

 buf_size = sizeof(sample) / sizeof(int);
 printf("Size of buffer(sample) is %d\n", buf_size);

 for (i = 0; i < buf_size; i++)
 {
   printf("element%2d: %d\n", i, sample[i]);
 }

 return 0;
}

sample.txtの中身

1,2,3,4

実験1(上記ソースコードをただ実行する)

 上記のソースコードを実行すると、#includeプリプロセッサがsample.txtの中身を読んで、配列を初期化してくれることが期待されます。実行してみた結果、実際にそうなりました。この時のコマンドプロンプトの表示を、Fig.1に示します。ファイルポインタを使わなくてよいことから、ファイルポインタ操作(fcloseとか)が不要になるのが便利ですね。

f:id:graziegrazie:20150721100927p:plain
Fig.1 サンプルコード実行時のコマンドプロンプト表示結果

実験2(配列のサイズをsample.txtの要素より少なくしてみる)

 #includeがsample.txtの中身を読んでいることから、例えばsample[3]とすると、コンパイルエラーが発生することが予想されます。実際に試してみた結果、Fig.2のようになりました。ファイルの中身を読んでいることがここから分かります。

f:id:graziegrazie:20150721102341p:plain
Fig.2 サンプルコード中の配列サイズをsample.txtの中身より小さくした時のコンパイル結果

まとめ

 C/C++では、配列の初期化に#includeプリプロセッサを使い、初期化時にファイルの中身を直接配列に保存することができます。これにより、ファイルポインタの解放忘れがなくなり、メモリ関係のトラブル要因を1つ消すことができます。また、実行環境でファイルを読まなくてよいので、秘密なデータを配列に保存したい時、セキュリティの面から有用だと思います。
 また、配列サイズを指定する・しないをうまく使い分けることで、様々なメリットがあると考えます。自分の考えとしては、
 -サイズを指定する →読み込むファイルの中身のサイズが固定
           →読み込むファイルが想定したファイルか、フォーマットになっているかが確認できる

 -サイズを指定しない→読み込むファイルのフォーマットが変わっても、柔軟に対応することができる
というメリットがあると思います。
 ただし、#includeを使って配列を初期化すると、コンパイル時に配列サイズが決まってしまいます。つまり、ファイルの中身を変更しそれを配列に反映したい時、再コンパイルが必要になります。この点には注意が必要になります。

Discriminative ModelとGenerative Model

 機械学習のモデルには、大別してGenerative ModelとDiscriminative Modelの2種類があります。今回はそれぞれの違いについて、簡単にまとめてみます。

 両者の違いを端的に言うと、モデル化時に検討する要素の違いです。
・Generative Model : 注目変数だけでなく、全ての変数を考慮
・Discriminative Model: 注目変数のみ考慮

Generative Model(生成モデル)

 生成モデルという名の通り、システムの全データの生成プロセスをモデル化します。そして、必要に応じてベイズ推定を行います。例えばGMMやLDAがこのモデルに属します。

Discriminative Model(識別モデル)

 識別モデルという名の通り、入力データを単純に識別します。モデル化には条件付き確率が使われます。同時分布が必要ない時に活躍します。例えばSVMがこのモデルに属します。