LoginSignup
4
11

More than 5 years have passed since last update.

階層的クラスタリング

Posted at

階層的クラスタリング

「都道府県別アルコール類の消費量」を例に説明します。

#(シャープ)以降の文字はプログラムに影響しません。
# 図やグラフを図示するためのライブラリをインポートする。
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
%matplotlib inline
# 数値計算やデータフレーム操作に関するライブラリをインポートする
import numpy as np
import pandas as pd
from pandas.tools import plotting # 高度なプロットを行うツールのインポート
# URL によるリソースへのアクセスを提供するライブラリをインポートする。
# import urllib # Python 2 の場合
import urllib.request # Python 3 の場合
# ウェブ上のリソースを指定する
url = 'https://raw.githubusercontent.com/maskot1977/ipython_notebook/master/toydata/sake_dataJ.txt'
# 指定したURLからリソースをダウンロードし、名前をつける。
# urllib.urlretrieve(url, 'sake_dataJ.txt') # Python 2 の場合
urllib.request.urlretrieve(url, 'sake_dataJ.txt') # Python 3 の場合
df = pd.read_csv('sake_dataJ.txt', sep='\t', index_col=0) # データの読み込み
df

行列の正規化

行列の正規化を行います。行列の正規化について、詳しくはPandas を用いた演算を参照のこと。

# 行列の正規化
dfs = df.apply(lambda x: (x-x.mean())/x.std(), axis=0).fillna(0)
# 正規化を終えた行列
dfs

クラスタリングについて

クラスタリングには色んな metric と method があるので、その中から一つを選択する。
* Metric (「距離」の定義)
* braycurtis
* canberra
* chebyshev
* cityblock
* correlation
* cosine
* euclidean
* hamming
* jaccard
* Method (結合方法)
* single
* average
* complete
* weighted

詳しくは、例えば クラスタリング手法のクラスタリングなどを参照のこと。

クラスタリングの実行

Metricからどれかひとつ、Methodからどれかひとつ選んで実行する。エラーが起こったり、あるいは「計算はできたけど、なんかこの結果はしっくり来ないな(解釈しづらいな)」と思ったら、別の方法を試す。

# metric は色々あるので、ケースバイケースでどれかひとつ好きなものを選ぶ。
# method も色々あるので、ケースバイケースでどれかひとつ好きなものを選ぶ。
#y_labels.append("1")
from scipy.cluster.hierarchy import linkage, dendrogram
result1 = linkage(dfs.iloc[:, :], 
                  #metric = 'braycurtis', 
                  #metric = 'canberra', 
                  #metric = 'chebyshev', 
                  #metric = 'cityblock', 
                  metric = 'correlation', 
                  #metric = 'cosine', 
                  #metric = 'euclidean', 
                  #metric = 'hamming', 
                  #metric = 'jaccard', 
                  #method= 'single')
                  method = 'average')
                  #method= 'complete')
                  #method='weighted')
#dendrogram(result1, labels = list(df.iloc[:, 0:1]))
plt.figure(figsize=(8, 8))
dendrogram(result1, orientation='right', labels=list(df.index), color_threshold=0.8)
plt.title("Dedrogram")
plt.xlabel("Threshold")
plt.grid()
plt.show()

同じデータを用いて、別の方法を実行した結果を以下に示します。どの方法がベストかはケースバイケースで、データの性質をよく考えた上で解釈しなければいけません。

# metric は色々あるので、ケースバイケースでどれかひとつ好きなものを選ぶ。
# method も色々あるので、ケースバイケースでどれかひとつ好きなものを選ぶ。
#y_labels.append("1")
from scipy.cluster.hierarchy import linkage, dendrogram
result1 = linkage(dfs.iloc[:, :], 
                  #metric = 'braycurtis', 
                  #metric = 'canberra', 
                  #metric = 'chebyshev', 
                  #metric = 'cityblock', 
                  #metric = 'correlation', 
                  #metric = 'cosine', 
                  metric = 'euclidean', 
                  #metric = 'hamming', 
                  #metric = 'jaccard', 
                  #method= 'single')
                  #method = 'average')
                  #method= 'complete')
                  method='weighted')
#dendrogram(result1, labels = list(df.iloc[:, 0:1]))
plt.figure(figsize=(8, 8))
dendrogram(result1, orientation='right', labels=list(df.index), color_threshold=0.8)
plt.title("Dedrogram")
plt.xlabel("Threshold")
plt.grid()
plt.show()

行と列を入れ替えてクラスタリング

行列の転置を行えば、行と列を入れ替えたクラスタリングが行えます。行列の転置について、詳しくはPandas を用いた演算を参照のこと。

# metric は色々あるので、ケースバイケースでどれかひとつ好きなものを選ぶ。
# method も色々あるので、ケースバイケースでどれかひとつ好きなものを選ぶ。
#y_labels.append("1")
from scipy.cluster.hierarchy import linkage, dendrogram
result1 = linkage(dfs.T.iloc[:, :], 
                  #metric = 'braycurtis', 
                  #metric = 'canberra', 
                  #metric = 'chebyshev', 
                  #metric = 'cityblock', 
                  metric = 'correlation', 
                  #metric = 'cosine', 
                  #metric = 'euclidean', 
                  #metric = 'hamming', 
                  #metric = 'jaccard', 
                  #method= 'single')
                  method = 'average')
                  #method= 'complete')
                  #method='weighted')
#dendrogram(result1, labels = list(df.iloc[:, 0:1]))
#plt.figure(figsize=(8, 8))
dendrogram(result1, orientation='right', labels=list(df.columns), color_threshold=0.05)
plt.title("Dedrogram")
plt.xlabel("Threshold")
plt.grid()
plt.show()
# metric は色々あるので、ケースバイケースでどれかひとつ好きなものを選ぶ。
# method も色々あるので、ケースバイケースでどれかひとつ好きなものを選ぶ。
#y_labels.append("1")
from scipy.cluster.hierarchy import linkage, dendrogram
result1 = linkage(dfs.T.iloc[:, :], 
                  #metric = 'braycurtis', 
                  #metric = 'canberra', 
                  #metric = 'chebyshev', 
                  #metric = 'cityblock', 
                  #metric = 'correlation', 
                  #metric = 'cosine', 
                  metric = 'euclidean', 
                  #metric = 'hamming', 
                  #metric = 'jaccard', 
                  #method= 'single')
                  #method = 'average')
                  #method= 'complete')
                  method='weighted')
#dendrogram(result1, labels = list(df.iloc[:, 0:1]))
#plt.figure(figsize=(8, 8))
dendrogram(result1, orientation='right', labels=list(df.columns), color_threshold=0.05)
plt.title("Dedrogram")
plt.xlabel("Threshold")
plt.grid()
plt.show()

上記の例では、方法を変えても同じような形のデンドログラムが生じたので、都道府県ごとの消費量を元にした「酒類間の類似関係」はクラスタリング方法の違いによらず一定の解釈ができそうである。

4
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
11