階層型クラスタリングによる視覚化

遺伝子や試験区の類似性を2次元に視覚化する
デンドログラムの例

遺伝子群や、実験間の関係を考えるときに、ちょっとその関係を視覚化できると考える助けになるだろう。
クラスタリングはこのための方法である。
考え方として、「似たものを集める」方法と、「集団を区切る」方法がある。
階層型クラスタリングは前者であり、似ているものをグルーピングしたデンドログラムを出力する。→

測定値のzスコア、またはその平均からの差とって、
そのひとつひとつの中から最も近いもの同士をクラスターにして平均をとり、
その平均と最も近い次のクラスターとをまとめて平均をとり、...
そして最終的にひとつのクラスターにまとめるまで計算をする。

注意すべきアーティファクトとして、chaining という現象がある。
平均をとりつづけると「とんがった特徴」がなくなっていくので、
そのクラスターが「どれからも近い」無敵状態になってしまう。
これは、大きな平均クラスターが、
雪だるま式に小さいクラスターをまきこんでいくことから発見できる。

また、たぶんこれと関連するのだけど、
本来は似ているのに(統合の順番の問題で)仲間外れになってしまうこともある。
右のケースでも、たとえば一番下の2データのクラスターは
ちょっとワリを喰っている感がある。

「集団を区切る」方法であり、k-means法や自己組織化写像SOMなどの方法がある。
De Hoonさん作のclusterというソフトウエアでも実行される。
実験間の関係を視覚化する、という目的ではあまり使わないかもしれない。

当然、クラスタリングの結果は、遺伝子発現の違いをどう考えるのかによって変わる。
ある遺伝子1のプローブについて、zスコアに標準化された2つのデータ、
サンプルA 1とサンプルB 1の違いは、差で考えればいい。

sample A sample B
gene 1 A 1 <-> B 1

D(A,B) = A 1 - B 1
ただしD(A,B)はA, B間の距離

この値は、トランスクリプトレベルのログレシオに比例すると考えられる。
ところが、クラスタリングで扱うのはそのひとつの遺伝子ではない。
測定される遺伝子は複数あるので、それらをどう合算すればいいのかは、ちょっとした問題である。
つまりサンプルAとサンプルBの違い(ないし距離)を、各遺伝子の差からどう考えるかだ。

sample A <-> sample B
gene 1 A 1 B 1
gene 2 A 2 B 2
gene 3 A 3 B 3
gene n A n B n

さらに、それらのサンプルは集められてクラスタをつくる。
各クラスタ間の距離をどう考えたらいいだろう?

Cluster 1 <-> Cluster 2
sample A sanple G
sample B sample H
sample C sample I

熱力学モデルから考えるならば、それぞれの遺伝子の動きはタンパク質因子の働きの結果である。この働きはエネルギーで表すことができるので、因子ごとのエネルギーの2乗和の平方根で距離がだせるだろう(ユークリッド距離)。ただ現時点ではその因子ごとの分解は不可能、遺伝子発現変化を因子に還元することができないからだ。

ひとつひとつの遺伝子発現の増減を全て直交した次元での出来事として考えるのなら、
サンプル間の距離はユークリッド距離で表せばいいだろう。
ちょうど、たとえば三次元座標のなかの2点間の距離を表すように。

さて、クラスタリングの対象は全ての遺伝子ではないことが多い、
むしろ何らかの観点で選択されているのが普通である
(それに、各チップのコンテンツは、そもそも微妙に異なっている)。
単純なユークリッド距離を使用すると、
対象とする遺伝子数に距離が依存することになる
(遺伝子数が増えると距離も遠くなる)。
その結果を標準化するためには、2乗和をデータ数で割って平均をとればいい。

mml D(A,B) = {Σ(A n - B n) 2/n} 1/2

さて、実際には各遺伝子の発現は独立しておらず、
たぶん一桁か二桁くらい小さい数のタンパク質因子によって制御されている。
しかも、マイクロアレイで比較しようとしているような二つの条件の間では、
そんなに多くの因子が変わっているわけではないだろう
(たいてい、ちょっとした条件の差のもとで測定・比較するからだ)。

もし、たった一つの因子が起こした変化を、
その因子に制御されている遺伝子群だけから推定するなら、
1次元のcity-block distanceで考えるべきだ。
遺伝子を絞った状態でクラスタリングをするときがこちらに相当するだろう。
もちろん、この場合も遺伝子の数で標準化するべきである。

mml D(A,B) = Σ (| A n - B n|) /n

遺伝子差をまとめたサンプル間差をどうまとめるか。
それぞれのサンプルのaverageないしmedianを使えばいいのではないか
と思う...が、これはアレイデータにつきものの生物学的なノイズ(個体差)
を考慮することができなくて、最初の足が長くなってしまう。

ノイズの考慮ということではWard's method が推奨されているようだけど
距離が分散(というか二乗和)で定義されているので、
距離ではなくて面積になってしまうので、そのままでは使えない。

Ward's methodは、クラスター間の距離を、それぞれのクラスター内外のばらつきの差で定義する。
クラスターC 1と C 2間の距離を、
mml D(C 1, C 2) = E(C 1 ∪ C 2)-E(C 1)-E(C 2)
ただしE(A)は、x i∈Aであるx iについて
E(A)=Σ (x i -mean(x i) )2

ゴメンナサイ、この件は現時点で考え中です。
とりあえずaverageで出しています。

Rを使わないなら:
De Hoonさん作のclusterと、 EisenさんのTreeViewの組み合わせで計算できる。

Rを使うなら:
#X にクラスタリングしたいデータをまとめておく。たとえばdatという行列が、
#columnでサンプル、rowで遺伝子が並んでいる場合、転置しておく。
#(普通ならXは横に長い行列になっているはず)。
#また、すでに遺伝子を絞ってあるものとする。

X <- t(dat) data_distances <- dist(x=X, method = "manhattan", diag=F)

# normalizing the distance by the number of genes
data_distances <- data_distances/dim(X)[2]

# making the dendrogram
data_dendrogram <- hclust(data_distances, "average")

# output
plot(data_dendrogram, ylab="City Block Distance, Average linkage", axes=F, xlab="", hang=-1)
axis(2)
これは後述するPCAのついでに(?)ぱっと出せるので、好都合。