web-dev-qa-db-ja.com

scipyによって作成された樹状図のカラークラスターに対応するフラットクラスタリングを取得する方法

投稿されたコードを使用して ここ 、私は素敵な階層的クラスタリングを作成しました:

scipy dendrogram

左側の樹状図が次のようなことを行って作成されたとしましょう

Y = sch.linkage(D, method='average') # D is a distance matrix
cutoff = 0.5*max(Y[:,2])
Z = sch.dendrogram(Y, orientation='right', color_threshold=cutoff)

ここで色付きの各クラスターのメンバーのインデックスを取得するにはどうすればよいですか?この状況を単純化するには、上部のクラスターを無視し、焦点を合わせるだけです。マトリックスの左側の樹状図。

この情報は、樹状図Z保存変数に保存する必要があります。 fclusterと呼ばれるものを実行する必要がある関数があります(ドキュメント ここ を参照)。ただし、樹状図の作成で指定したのと同じcutoffをfclusterに指定できる場所がわかりません。 fclustertのしきい値変数は、さまざまなあいまいな測定値(inconsistentdistancemaxclust)の観点からでなければならないようです。 、monocrit)。何か案は?

19
conradlee

あなたは正しい方向に進んでいると思います。これを試してみましょう:

import scipy
import scipy.cluster.hierarchy as sch
X = scipy.randn(100, 2)     # 100 2-dimensional observations
d = sch.distance.pdist(X)   # vector of (100 choose 2) pairwise distances
L = sch.linkage(d, method='complete')
ind = sch.fcluster(L, 0.5*d.max(), 'distance')

indは、100個の入力観測値のそれぞれのクラスターインデックスを提供します。 indは、methodで使用したlinkageによって異なります。 method=singlecomplete、およびaverageを試してください。次に、indの違いに注意してください。

例:

In [59]: L = sch.linkage(d, method='complete')

In [60]: sch.fcluster(L, 0.5*d.max(), 'distance')
Out[60]: 
array([5, 4, 2, 2, 5, 5, 1, 5, 5, 2, 5, 2, 5, 5, 1, 1, 5, 5, 4, 2, 5, 2, 5,
       2, 5, 3, 5, 3, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 4, 1, 4, 5, 2, 1, 4,
       2, 4, 2, 2, 5, 5, 5, 2, 5, 5, 3, 5, 5, 4, 5, 4, 5, 3, 5, 3, 5, 5, 5,
       2, 3, 5, 5, 4, 5, 5, 2, 2, 5, 2, 2, 4, 1, 2, 1, 5, 2, 5, 5, 5, 1, 5,
       4, 2, 4, 5, 2, 4, 4, 2])

In [61]: L = sch.linkage(d, method='single')

In [62]: sch.fcluster(L, 0.5*d.max(), 'distance')
Out[62]: 
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1])

scipy.cluster.hierarchy確かに紛らわしいです。あなたのリンクでは、私は自分のコードさえ認識していません!

18
Steve Tjoa

リンケージマトリックスを凝縮解除するコードをいくつか書きました。凝集ステップごとにグループ化されたlabelsのインデックスを含む辞書を返します。 completeリンケージクラスターの結果でのみ試してみました。 dictのキーはlen(labels)+1で始まります。これは、最初は各ラベルが独自のクラスターとして扱われるためです。これはあなたの質問に答えるかもしれません。

import pandas as pd
import numpy as np
from scipy.cluster.hierarchy import linkage

np.random.seed(123)
labels = ['ID_0','ID_1','ID_2','ID_3','ID_4']

X = np.corrcoef(np.random.random_sample([5,3])*10)
row_clusters = linkage(x_corr, method='complete')    

def extract_levels(row_clusters, labels):
    clusters = {}
    for row in xrange(row_clusters.shape[0]):
        cluster_n = row + len(labels)
        # which clusters / labels are present in this row
        glob1, glob2 = row_clusters[row, 0], row_clusters[row, 1]

        # if this is a cluster, pull the cluster
        this_clust = []
        for glob in [glob1, glob2]:
            if glob > (len(labels)-1):
                this_clust += clusters[glob]
            # if it isn't, add the label to this cluster
            else:
                this_clust.append(glob)

        clusters[cluster_n] = this_clust
    return clusters

戻り値:

{5: [0.0, 2.0],
 6: [3.0, 4.0],
 7: [1.0, 0.0, 2.0],
 8: [3.0, 4.0, 1.0, 0.0, 2.0]}

cut_tree 、超距離に必要なものを提供する高さパラメーターがあります。

1
emem

これはゲームに非常に遅れていることは知っていますが、投稿のコードに基づいてプロットオブジェクトを作成しました ここ 。それはpipに登録されているので、インストールするには電話するだけです

pip install pydendroheatmap

ここでプロジェクトのgithubページをチェックしてください: https://github.com/themantalope/pydendroheatmap

1
themantalope