日本国債 主成分分析

主成分分析

イールドカーブの変動をいくつかの変動パターンに分離する手法。
イールドカーブ変動は、利回りの水準変化、傾き変化、曲率変化の3つで90%以上説明できるとされる。
実際のデータをみてみる。

モジュールのインポート

import matplotlib.pyplot as  plt
import pandas as pd
import numpy as np
import requests 
import io
import datetime
from sklearn.decomposition import PCA

データ取得。財務省より。1~40年のうち欠損がある期間は除外

#データ取得
url = 'https://www.mof.go.jp/jgbs/reference/interest_rate/data/jgbcm_all.csv'
res = requests.get(url)
df = pd.read_csv(io.StringIO(res.text),sep=',',header=1,index_col=0,encoding="UTF-8").dropna()
df.index.name = None
#欠損を削除
df =df[~df.apply(lambda x: x.astype(str) == "-").any(axis=1)]
df = df.astype(float)

日付などをきれいにする。

def convert_wareki_to_seireki(wareki_date):
    era = wareki_date[0]
    year, month, day = map(int, wareki_date[1:].split('.'))
    if era == 'S':
        seireki_year = 1925 + year
    elif era == 'H':
        seireki_year = 1988 + year
    elif era == 'R':
        seireki_year = 2018 + year
    seireki_date = datetime.date(seireki_year, month, day)    
    return seireki_date

df.index = pd.to_datetime([convert_wareki_to_seireki(i) for i in df.index])
df.columns = [i[:-2]+"y" for i in df.columns]

#変化量
df_ = df.diff().dropna()

計算期間を250日とし、ローリングで主成分分析。

## 
window = 250
sft = pd.DataFrame()
twst= pd.DataFrame()
curv= pd.DataFrame()

cnt = pd.DataFrame()
for i in range(window,len(df_)):
    tmp=  df_.iloc[i-window:i]
    
    mean = tmp.mean()
    std = tmp.std()
    data = (df_-mean)/std
    pca = PCA()
    pca.fit(data)
    eigenvector = pd.DataFrame(pca.components_, columns=df.columns, index=["PC{}".format(x + 1) for x in range(len(df.columns))])
    sft = pd.concat([sft,pd.DataFrame(pca.components_[0]).T])
    twst = pd.concat([twst,pd.DataFrame(pca.components_[1]).T])
    curv =  pd.concat([curv,pd.DataFrame(pca.components_[3]).T])
    cnt = pd.concat([cnt,pd.DataFrame(pca.explained_variance_ratio_[0:3]).T])
sft.index=twst.index=curv.index = cnt.index =  df_.index[window:]
sft.columns=twst.columns=curv.columns = df.columns
cnt.columns = ["shift","twist","curvature"]

plt.figure(figsize=(10,6))
plt.axhline(y=0, color='black', linestyle='--')
plt.plot(sft.iloc[-1,:],label="shift")
plt.plot(twst.iloc[-1,:],label="twist")
plt.plot(curv.iloc[-1,:],label="curvature")
plt.legend()
plt.show()

出力は下記。
第一主成分は全年限符号が同じ
  →イールドカーブ変動の水準変化
第二主成分は9年付近で符号が変化
  →イールドカーブ変動の傾き変化
第三主成分は(1年は置いておくとして)符号が-+-となっている
  →イールドカーブの曲率変化

足許の寄与度

第一主成分の寄与度推移。

plt.figure(figsize=(10,6))
plt.plot(cnt["shift"],color ="blue",label = "shift")
# plt.twinx()
# plt.plot(df["10y"],label="10y")
plt.legend()
plt.show()
plt.figure(figsize=(10,6))
plt.plot(cnt["twist"],color ="orange",label = "twist")
plt.plot(cnt["curvature"],color ="green",label = "curvature")
plt.legend()
plt.show()

70%超が第一主成分で説明できる

第一主成分
第二、第三主成分
第一主成分と10年利回りの推移

相関。割と高い。

この記事が気に入ったらサポートをしてみませんか?