アセットマネージャーのためのファイナンス機械学習:クラスタリング ベースクラスタリング

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

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