階層クラスタリング
頭が整理できていないので、メモ
まとめること
キーワード
scipy.cluster.hierarchy
condensed distance matrix
redundant distance matrix
square-form distance matrix
やりたいこと
日株(TOPIX),米株(S&P500),日債,米債の4種資産を、相関関係をもとに階層クラスタリングで分類したい。
使用するライブラリ
scipy.cluster.hierarchy
公式ドキュメント
引数に何を投入すればよい?
以下、公式ドキュメントより引用(linkage
のところ)
Performs hierarchical/agglomerative clustering on the condensed distance matrix y.
距離行列を投入すればおっけーみたい。でも、condensed distance matrix
とは?
距離行列関連
そもそも
今回の目的は相関関係をもとにクラスタ分けを行うことなので、相関係数行列をもとに4資産間の距離行列を算出することにしている。
具体的には、この論文で用いられている下の関数を使用。
def correlDist(corr): # A distance matrix based on correlation, where 0<=d[i,j]<=1 # This is a proper distance metric dist = ((1 - corr) / 2.) ** .5 # distance matrix return dist
例として、投入した相関係数行列と、出力された距離行列の組み合わせは以下。
相関係数行列 距離行列
距離行列の種類
公式ドキュメント内のcondensed distance matrix
とは??というところから、距離行列の表記種類(距離の測定方法でなはくて)を自身の調べた限りでまとめてみる。
参考サイトは以下。
square-form distance matrix
おそらく最も馴染みのある形式。上の関数の出力dist
と同じ形式
condensed distance matrix
距離行列って「対象行列」かつ「対角成分は0」を満たすから、square-form distance matrix
って無駄な情報多くない?っていう考え方から作成されたもの
square-form distance matrix
をもとに、以下のコードで変換可能。
from scipy.spatial.distance import squareform condensed_dist = squareform(dist) # dist : squared_form
redundant distance matrix
調べても出てこなかった、、
ただ、下のリンクではcondensed
と対比して使われていることとredundant
の「余分な」という意味と合わせて考えるとsquared_form
と同じ意味ではないかと。
github.com
実装コード
引数もわかったことだし、コードを実装したのが以下。 ( (きってはってしたので、インテンドとかめちゃくちゃです、すみません。)
import scipy.cluster.hierarchy as sch from scipy.cluster.hierarchy import dendrogram from scipy.spatial.distance import squareform def correlDist(corr): # A distance matrix based on correlation, where 0<=d[i,j]<=1 # This is a proper distance metric dist = ((1 - corr) / 2.) ** .5 # distance matrix return dist corr = input_df.corr() dist = self.correlDist(corr) # dist行列を使用 condensed_dist = squareform(dist) link = sch.linkage(condensed_dist, method='ward', metric='euclidean') # 樹形図保存 fig = dendrogram(link, labels=self.corr.index.values) plt.xticks(rotation=315, ha='left') plt.savefig("output/dendrogram.png", bbox_inches='tight', pad_inches=0) plt.figure()
樹形図見た感じよさそう。一応linkage
を確認。linkage
各要素については、以下リンクを参考。
linkage
の出力結果は以下。
[[0. 1. 0.65309278 2. ] [2. 3. 0.66734477 2. ] [4. 5. 0.89813174 4. ]]
4資産間の距離は以下の通り。(見やすいのでsquared_form
)
index0:日株とindex1:米株の距離、およびindex2:日債とindex3:米債の距離が投入したものと同じであることが確認できた。
ところで
上のこのリンク内で、
「scipy.cluster.hierarchy
ってredundant distance matrix
いれても大丈夫、とかいってるけど、実際にいれてみたらdistance matrix
のことをobserved matrix
と勘違いしてません??」
みたいなこと言われていたのが気になる。。(この論文中ではsquared_form
の距離行列をそのままscipy
につっこんでるし)
確認してみた。
import scipy.cluster.hierarchy as sch from scipy.cluster.hierarchy import dendrogram from scipy.spatial.distance import squareform def correlDist(corr): # A distance matrix based on correlation, where 0<=d[i,j]<=1 # This is a proper distance metric dist = ((1 - corr) / 2.) ** .5 # distance matrix return dist corr = input_df.corr() dist = self.correlDist(corr) # dist行列を使用 #condensed_dist = squareform(dist) #link = sch.linkage(condensed_dist, method='ward', metric='euclidean') link = sch.linkage(dist, method='ward', metric='euclidean') # 樹形図保存 fig = dendrogram(link, labels=self.corr.index.values) plt.xticks(rotation=315, ha='left') plt.savefig("output/dendrogram.png", bbox_inches='tight', pad_inches=0) plt.figure()
linkage
はこちら
[[0. 1. 0.93768267 2. ] [2. 3. 0.95778144 2. ] [4. 5. 1.2899719 4. ]]
データ間の距離は確かに変わっちゃってる。そして、dist
を観測行列として求めたデータ間のユークリッド距離と一致していた。
うーーん、まあこれでもデータ間のユークリッド距離の大小関係は崩れないとおもうんだけど、なんか気持ち悪さは残る、、(でも前会社で「別にこれでも(多分)大小関係崩れないからよくないですか??」とか適当に言ったことはある)
まあcondensed distance matrix
を投入すればいいだけの話かなあ。