アセットマネージャーのためのファイナンス機械学習:クラスター数 ONCアルゴリズム モンテカルロ
ブロックの数と構成を再現するONCアルゴリズムを使い、行と列をシャッフルされた$${M \ge 2}$$のサイズのブロックK個からなる$${N\times N}$$のランダムな相関行列を復元する。
$${N=16,32,64}$$、$${K=3,6,\dots N/2}$$、試行回数を100、ONCアルゴリズムによって決定されたクラスター数の$${E[K]}$$の$${K}$$からの乖離$${E[K]/K}$$として表し、$${K/N}$$毎に示す。
モンテカルロシミュレーションのコードは以下の通りである。
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples
from scipy.linalg import block_diag
from sklearn.utils import check_random_state
import MarPat as MP
import ONC
import pickle
def ShuffleMatrix(bCorr,random_state=None):
rng=check_random_state(random_state)
corr0=pd.DataFrame(bCorr)
cols=corr0.columns.tolist()
rng.shuffle(cols)
corr0=corr0[cols].loc[cols].copy(deep=True)
return corr0
N=[16,32,64]
M=2
num=100
print('start')
for n in N:
print(n)
results={}
file_name=f'results_{n}'
for k in range(3,int(n/2)+1,3):
key=k/n
E=0
for i in range(1,num):
corr0 = ONC.randomBlockCorr(n, k, minBlockSize=M)
corr1 = ShuffleMatrix(corr0)
corr1New, clstrs1New, silh1New = ONC.clusterKMeansTop(corr1)
E=len(clstrs1New)/k
results.setdefault(key,[]).append(E)
with open(file_name, 'wb') as fp:
pickle.dump(results, fp)
print('dictionary saved successfully to file')
print('sim end')
ONCは決して効率の良いコードではなく、Nが大きくなればなるほど時間がかかるので、計算時間の関係から結果をファイルに書き出している。
シミュレーション結果の計算処理は重くはないので、ファイルを読み込んで行う。
import pickle
from collections import defaultdict
import pandas as pd
results = defaultdict(list)
N=[16,32,64]
for n in N:
file_name='results_'+str(n)
with open(file_name,'rb') as fp:
result = pickle.load(fp)
for key,val in result.items():
results[key]+=val
df=pd.DataFrame()
for mky,mv in results.items():
n_mv=len(mv)
avg=sum(mv)/n_mv
err=0.0
for i in range(n_mv):
err+=(mv[i]-avg)*(mv[i]-avg)
err/=n_mv
list_=[[mky,round(avg,3),round(err,8)]]
df_new=pd.DataFrame(list_,columns=['K/N','E[K]/K','ERR'])
df=pd.concat([df,df_new])
シミュレーション結果は辞書形式で、keyを$${K/N}$$、値をリスト形式にして平均値と平均二乗誤差を計算し、データフレームで出力した。
$${K/N}$$が小さい値ではエラーが見られるが、$${K/N \ge 0.3}$$では良い結果を出していると言える。
この記事が気に入ったらサポートをしてみませんか?