階層的クラスタリング
やること
階層的クラスタリングについて、手を動かしてみる
参考サイト
今回も参考サイトを写した
やったこと
都道府県別アルコール消費量のデータをもとに、47都道府県をクラスタリング!
とりあえず、参考サイトの言われるままに、データをダウンロードしてデータフレーム作成
%matplotlib inline import urllib.request import pandas as pd import matplotlib.pyplot as plt from scipy.cluster.hierarchy import linkage, dendrogram url = 'https://raw.githubusercontent.com/maskot1977/ipython_notebook/master/toydata/sake_dataJ.txt' urllib.request.urlretrieve(url,'sake_dataJ.txt') df = pd.read_csv('sake_dataJ.txt', sep = '\t', index_col = 0) print (df.head(7))
結果
Sake Shochu Bear Wine Whisky Pref Hokkaido 46476000 50642000 315300000 10488000 9749000 Aomori 17273000 11503000 83164000 1774000 3122000 Iwate 17120000 10220000 67803000 1458000 1870000 Miyagi 27859000 11768000 109850000 2824000 5049000 Akita 24153000 6240000 67894000 1242000 2099000 Yamagata 20570000 6067000 61130000 1706000 2466000 Fukushima 31016000 11166000 100122000 1885000 3807000
特徴量行列を変えてみる
参考記事で書かれている通り、特徴量行列を色々変えてみる
正しいやつ
都道府県別アルコール消費量のデータフレームを、行ごとに正規化
正規化した特徴量行列を用いて、クラスタリング
dfs = df.apply(lambda x: (x - x.mean()) / x.std(), axis = 1).fillna(0) print (dfs.head(7)) result1 = linkage(dfs.iloc[:, :], metric = 'correlation', method = 'average') plt.figure(figsize=(8, 8)) dendrogram(result1, orientation='right', labels=list(df.index), color_threshold=0.01) plt.title("Dedrogram") plt.xlabel("Threshold") plt.show()
結果
Sake Shochu Bear Wine Whisky Pref Hokkaido -0.309710 -0.277498 1.768869 -0.587973 -0.593687 Aomori -0.179131 -0.348733 1.757648 -0.634704 -0.595081 Iwate -0.093054 -0.342479 1.739063 -0.659212 -0.644319 Miyagi -0.080427 -0.438818 1.745738 -0.638025 -0.588468 Akita 0.135911 -0.500179 1.689151 -0.677657 -0.647225 Yamagata 0.087023 -0.491336 1.704499 -0.665247 -0.634939 Fukushima 0.034493 -0.448771 1.716934 -0.674724 -0.627932
列ごとに正規化しちゃったパターン
# dfs = df.apply(lambda x: (x - x.mean()) / x.std(), axis = 1).fillna(0) dfs1 = df.apply(lambda x: (x - x.mean()) / x.std(), axis = 0).fillna(0) print (dfs1.head(7)) result1 = linkage(dfs1.iloc[:, :], metric = 'correlation', method = 'average') plt.figure(figsize=(8, 8)) dendrogram(result1, orientation='right', labels=list(df.index), color_threshold=0.01) plt.title("Dedrogram") plt.xlabel("Threshold") plt.show()
結果
Sake Shochu Bear Wine Whisky Pref Hokkaido 0.811237 2.147580 1.057634 1.029017 1.207049 Aomori -0.437580 -0.210625 -0.389028 -0.298893 -0.126779 Iwate -0.444123 -0.287929 -0.484757 -0.347047 -0.378772 Miyagi 0.015112 -0.194659 -0.222722 -0.138885 0.261072 Akita -0.143369 -0.527732 -0.484190 -0.379963 -0.332681 Yamagata -0.296590 -0.538156 -0.526343 -0.309255 -0.258814 Fukushima 0.150116 -0.230930 -0.283346 -0.281978 0.011092
全然違う結果になった
正規化しなかったパターン
print (df.head(7)) result1 = linkage(df.iloc[:, :], metric = 'correlation', method = 'average') plt.figure(figsize=(8, 8)) dendrogram(result1, orientation='right', labels=list(df.index), color_threshold=0.01) plt.title("Dedrogram") plt.xlabel("Threshold") plt.show()
結果
Sake Shochu Bear Wine Whisky Pref Hokkaido 46476000 50642000 315300000 10488000 9749000 Aomori 17273000 11503000 83164000 1774000 3122000 Iwate 17120000 10220000 67803000 1458000 1870000 Miyagi 27859000 11768000 109850000 2824000 5049000 Akita 24153000 6240000 67894000 1242000 2099000 Yamagata 20570000 6067000 61130000 1706000 2466000 Fukushima 31016000 11166000 100122000 1885000 3807000
変えた結果について
そもそも行ごとに正規化する目的は、都道府県ごとの消費量の大小の影響を無くすこと(アルコール類の中で、どの種類の割合が多いかのみに着目して、クラスタリングするため)
だから、列ごとに正規化すると全然違う結果になる
一方、正規化しなかった場合と正規化した場合の結果は、違いがないように見られた
これはなぜ??