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

kmeans法の第3の修正は、クラスタ品質の不均一性への対処となる。base clusteringから得られた$${q}$$スコアリングを基に、$${q}$$の平均値$${\bar{q}}$$未満のクラスタの集合に含まれる数を$${K_I, K_I \lt K}$$とする。
$${K_I \le 1}$$であれば、クラスタリングを終了する。
$${K_I \le 2}$$の時、この平均未満の集合$${q_k| q_k\lt\bar{}q, k=1, \dots ,K_I}$$の要素にから新しい観測値行列を形成し再クラスタリングを行う。この結果の品質が向上していれば、この分割をbase clusteringで許容されたクラスタリングと結合する。
 この実装はスニペット4.2にある。

def makeNewOutputs(corr0,clstrs,clstrs2):
    clstrsNew={}
    for i in clstrs.keys():
        clstrsNew[len(clstrsNew.keys())]=list(clstrs[i])
    for i in clstrs2.keys():
        clstrsNew[len(clstrsNew.keys())]=list(clstrs2[i])
    newIdx=[j for i in clstrsNew for j in clstrsNew[i]]
    corrNew=corr0.loc[newIdx, newIdx]
    x=((1-corr0.fillna(0))/2.)**.5
    kmeans_labels=np.zeros(len(x.columns))
    for i in clstrsNew.keys():
        idx=[x.index.get_loc(k) for k in clstrsNew[i]]
        kmeans_labels[idx]=i
    silhNew=pd.Series(silhouette_samples(x,kmeans_labels),index=x.index)
    return corrNew,clstrsNew, silhNew


def clusterKMeansTop(corr0, maxNumClusters=None,n_init=10):
    if maxNumClusters==None:
        maxNumClusters=corr0.shape[1]-1

    corr1,clstrs,silh=clusterKMeansBase(corr0,
                           maxNumClusters=min(maxNumClusters,corr0.shape[1]-1),
                          n_init=n_init)
    clusterTstats={i:np.mean(silh[clstrs[i]])/np.std(silh[clstrs[i]])
                   for i in clstrs.keys()}
    tStatMean=sum(clusterTstats.values())/len(clusterTstats)
    redoClusters=[i for i in clusterTstats.keys() if clusterTstats[i]>tStatMean]
    if len(redoClusters)<2:
        return corr1, clstrs,silh
    else:
        keysRedo=[j for i in redoClusters for j in clstrs[i]]
        corrTmp=corr0.loc[keysRedo, keysRedo]
        tStatMean=np.mean([clusterTstats[i] for i in redoClusters])
        corr2, clstrs2,silh2=clusterKMeansBase(corrTmp,
                           maxNumClusters=min(maxNumClusters,corrTmp.shape[1]-1),
                          n_init=n_init)
        corrNew, clstrsNew,silhNew=makeNewOutputs(corr0,
                                                 {i:clstrs[i] for i in clstrs.keys()
                                                  if i not in redoClusters},clstrs2)
        newTstatMean=np.mean([np.mean(silhNew[clstrsNew[i]])/
                              np.std(silhNew[clstrsNew[i]]) 
                              for i in clstrsNew.keys()])
        if newTstatMean<tStatMean:
            return corr1,clstrs,silh
        else:
            return corrNew, clstrsNew,silhNew


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