ボトムアップ式のクラスタリングのグループ化
データ作成
shape: (5, 3) のランダム行列を作成
import pandas as pd import numpy as np np.random.seed(123) variables = ['X', 'Y', 'Z'] labels = ['ID_0', 'ID_1', 'ID_2', 'ID_3', 'ID_4'] X = np.random.random_sample([5, 3])*10 ## pandas のデータフレームに変更 df = pd.DataFrame(X, columns=variables, index=labels)
距離の計算
from scipy.spatial.distance import pdist, squareform ## pdist : 距離の計算 ## squareform : pdist にて算出した圧縮済みの距離行列から対称行列に変換 row_dist = pd.DataFrame(squareform(pdist(df, metric='euclidean')), columns=labels, index=labels)
from scipy.cluster.hierarchy import linkage # method='complete' : 完全連結法、 クラスタの中で一番距離の遠い点が違い順で凝縮する row_clusters = linkage(pdist(df, metric='euclidean'), method='complete')
階層的クラスタリングの実行
# no. of items in clust : クラスタの個数 pd.DataFrame( row_clusters, columns=[ 'row label 1', 'row label 2', 'distance', 'no. of items in clust.' ], index=['cluster %d' % (i +1) for i in range(row_clusters.shape[0])] )
- sklearnでの実行
from sklearn.cluster import AgglomerativeClustering ac = AgglomerativeClustering( n_clusters=3, affinity='euclidean', linkage='complete' ) labels = ac.fit_predict(X) print('Cluster labels: %s' % labels)
Cluster labels: [1 0 0 2 1]
連結行列を樹形図にて表す
from scipy.cluster.hierarchy import dendrogram row_dendr = dendrogram( row_clusters, labels=labels, ) plt.ylabel('Euclidean distance') plt.tight_layout() plt.show()
ヒートマップによる可視化
fig = plt.figure(figsize=(8, 8), facecolor='white') ## x 軸の位置、y 軸の位置、幅、高さ axd = fig.add_axes([0.09, 0.1, 0.2, 0.6]) ## orientation : 回転 row_dendr = dendrogram(row_clusters, orientation='left') ## クラスタリングのラベルは 'leaves'から取得する。 ## ヒートマップは右側に配置する df_rowclust = df.iloc[row_dendr['leaves'][::-1]] axm = fig.add_axes([0.23, 0.1, 0.6, 0.6]) cax = axm.matshow(df_rowclust, interpolation='nearest', cmap='hot_r') axd.set_xticks([]) axd.set_yticks([]) for i in axd.spines.values(): i.set_visible(False) fig.colorbar(cax) axm.set_xticklabels([''] + list(df_rowclust.columns)) axm.set_xticklabels([''] + list(df_rowclust.index)) plt.show()