mecobalamin’s diary

人間万事塞翁が馬

https://help.hatenablog.com/entry/developer-option

Rでクラスタリングとヒートマップ


Rでクラスタリングをしてその結果を
ヒートマップと樹状図で表示するには
pheatmapのライブラリを使う

クラスタリングだけならdist()とhclust()を使えばできるが、
ヒートマップも一緒にとなるとpheatmapかな
https://www1.doshisha.ac.jp/~mjin/R/Chap_28/28.html

他にもあるかもしれないけれど今の所探せてない

ライブラリのインストールは
RGuiの"パッケージ" -> "パッケージのインストール"で行う
CRANのミラーサイトを選んだら
pheatmapパッケージを選択してインストールする

もしくはこのコマンドでインストール

install.packages("pheatmap", dependencies = TRUE)

パッケージ | R のパッケージのインストール方法と呼び出し方

library(pheatmap)
MakingHeatMap <- function(m){

  # pngファイル名
  HeatName = sprintf("heatmap.png")

  # ヒートマップの色の範囲を指定する
  BreaksList <- seq(0, 8.0, by = 1)
  Col.Pal <- colorRampPalette(c("#0041ff", "#ffff99", "#ff2800"))
  Col.List <- Col.Pal(length(BreaksList))
 
  # ヒートマップを描く
  pheatmap(m,
    breaks = BreaksList,
    fontsize = 5,
    color = Col.List,
    cluster_rows = TRUE,
    cluster_cols = FALSE,
    display_numbers = TRUE,
    clustering_distance_rows = "euclidean",
    clustering_method = "ward.D2",
    number_color = "black",
    legend = TRUE,
    legend_breaks = BreaksList,
    legend_labels = BreaksList,
    treeheight_row = 200,
    width = 5,
    height = 10,
    main = sprintf("heatmap"),
    filename = HeatName
  )

出力はpng形式の画像になる
ヒートマップは0から8.0の範囲を1.0刻みで色付けする

pheatmap()の引数は行列
ヒートマップの行方向に樹状図を描くので

cluster_rows = TRUE

距離はeuclidean、クラスタリングの方法はward.D2
hclust()のward.Dは計算方法が間違っていて
ward.D2を使うようにとのことだったが
pheatmap()にも同じ問題があるかどうか未確認
内部でhclust()を呼び出していたら一緒かも

5 October 2019追記
pheatmapのマニュアル読むとhclustと同じ引数を使ってる
https://cran.r-project.org/web/packages/pheatmap/pheatmap.pdf

hclust()のward.Dはward法の実装ではないとのこと
https://data-science.gr.jp/implementation/ida_r_hierarchical_clustering.html

まだはっきりしないけどward法を使う場合は
ward.D2を指定するのが良さげ
追記ここまで


関数はこんなふうに呼び出す

# データの用意
Data.Iris <- iris
Par.List <- colnames(Data.Iris)
Sp.Num <- paste(Sp.Names, rep(1:50, 3), sep = ", ")
#d <- t(rbind(Data.Iris[,3], Data.Iris[,4]))
#colnames(d) <- c(Par.List[3], Par.List[4])
d <- Data.Iris[1:4]
rownames(d) <- Sp.Num

# グラフの作成
MakingHeatMap(d)

結果はこんな感じ

setosaはそれだけでまとまっていて
うまくクラスタリングできているように見える

樹状図のどこかでカットして
3つのグループに分けられれば正解だがどうだろう
1つ目はsetosa, 49とvirginica, 41の間っぽい

virginica, 36とversicolor, 11の間がもう一つの境目に見えるけど
どっちにもvirginicaとversicolorはなんか混じってる
散布図ではそもそもSepalはlength、widthともに
virginicaとversicolorの分離が悪い
petalは分離が良くなるのでpetal.lengthとpetal.widthで
クラスタリングしたのがこちら

versicolor, 47とvirginica, 39の間で分ければ
もう少しマシな感じで3つに分けられそう
散布図で重なっている部分の
クラスタリングが微妙なのかも

散布図との比較で判断したけど
判断の基準があるのかな