アセットマネージャーのためのファイナンス機械学習:クラスタリング ベースクラスタリング
k-means法を修正し、最適なクラスタ数を見つけるために、シルエット係数を用いて目的関数を導入する。
シルエット係数は、クラスタ$${i}$$に属するデータポイント$${\bf{x}^{(i)}}$$とクラスタ$${i}$$内の全てのデータポイントとの平均距離$${a^{(i)}}$$と、クラスタ$${i}$$に再隣接するクラスタ内の全てのデータポイントとの平均距離$${b^{i}}$$で定義される。
$${s_i=\displaystyle{\frac{b^{(i)}-a^{(i)}}{max\{b^{(i)}, a^{(i)}\}}}, i=1,\dots N}$$
ある分割について、目的関数として、クラスタリング品質の測定値$${q}$$を以下のように定義する。
$${q=\displaystyle{\frac{E[\{s_i\}]}{\sqrt{V[\{s_i\}]}} }}$$
初期化を改善するためには、ある初期化に関してkmeansクラスタリングを異なる$${k, k=2,\dots N}$$で試行するループを複数回繰り返し、この2重のループの結果から、最も高い$${q}$$のサンプリングを選択する。
この実装は、スニペット4.1で実装されている。
この関数は、相関係数が引数で渡され、前記事に従い、$${X_{ij}=\displaystyle{\sqrt{\frac{1-\rho_{ij}}{2}} }}$$なる$${\bf{X}}$$をkmeans分解に渡し、最も高い$${q}$$の分割に従って、渡された相関行列を並べ替え、クラスタラベルとシルエット係数と共に返している。
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples
def clusterKMeansBase(corr0,maxNumClusters=10, n_init=10):
x=((1-corr0.fillna(0))/2.)**.5 # the observed matrix for clustering
silh=pd.Series()
kmeans, stat = None, None
for init in range(n_init):
for i in range(2,maxNumClusters+1): # set the num. of clusters from 2,3...10
kmeans_=KMeans(n_clusters=i, n_init=n_init)
kmeans_=kmeans_.fit(x)
silh_=silhouette_samples(x,kmeans_.labels_)
stat=(silh_.mean()/silh_.std(),silh.mean()/silh.std())
if np.isnan(stat[1])or stat[0]>stat[1]:
silh,kmeans=silh_,kmeans_
newIdx=np.argsort(kmeans.labels_)
corr1=corr0.iloc[newIdx]
corr1=corr1.iloc[:,newIdx]
clstrs={i:corr0.columns[np.where(kmeans.labels_==i)[0]].tolist()
for i in np.unique(kmeans.labels_)}
silh=pd.Series(silh,index=x.index)
return corr1, clstrs,silh
この記事が気に入ったらサポートをしてみませんか?