情報科学と人工知能のノート

初等的な知識から最新論文の解説まで色々集めていきます.備忘録兼用.

主成分分析ってたぶんこういうもの

例によってさも分かってるかのように説明していますので間違ってたら教えてください。

たたき台

以下のように四次元の点が 10 個並んだ表があったとします。

> round(a, 3)
[,1] [,2] [,3] [,4]
[1,] -0.043 0.026 -0.005 -0.013
[2,] -1.314 0.785 -0.150 -0.414
[3,] 1.757 -1.049 0.201 0.554
[4,] -0.119 0.071 -0.014 -0.037
[5,] -0.963 0.575 -0.110 -0.303
[6,] 1.059 -0.633 0.121 0.334
[7,] 1.248 -0.745 0.143 0.393
[8,] -1.608 0.961 -0.184 -0.507
[9,] -1.149 0.686 -0.132 -0.362
[10,] 1.132 -0.676 0.130 0.357

これだけ見てもどういうデータなのかはよくわかりません。
しかし、これらのデータは実は以下のようにして作られたものだったのです。

> d1 <- rnorm(4) # 適当に方向ベクトルを定める
> d1 <- d1 / sqrt(d1 %*% d1) # 後の都合のために単位ベクトルにしておく
> c1 <- rnorm(10) # 適当に 10 個の倍率を定める
> c1 <- c1 - mean(c1) # 後の都合のために平均を 0 にしておく
> a <- t(mapply(function(x) return (d1 * x), c1)) # 方向を倍率倍

言葉で言うと、方向ベクトルを適当に定めて、適当に何倍かしただけです。
上記のデータがこのように作られたものであったならば、それぞれの点を読んでもよくわからない4次元の絶対座標で表すよりも、方向ベクトルの何倍なのかで表した方がデータを把握しやすくなりますよね。
このデータに対して主成分分析を行うと、今まさに欲しかった、各点が方向ベクトルの何倍なのかを求めることができます。
R で実行するのは簡単で、行列を princomp 関数に与えるだけです。

> res1 <- princomp(a)
> summary(res1)
Importance of components:
Comp.1 Comp.2 Comp.3 Comp.4
Standard deviation 1.414748 2.980232e-08 2.634178e-09 0
Proportion of Variance 1.000000 4.437535e-16 3.466824e-18 0
Cumulative Proportion 1.000000 1.000000e+00 1.000000e+00 1

細かい説明は省きますが Proportion of Variance の左端が 1 になっていますよね。
これはおおざっぱに言うと、データが1次元に並んでいましたという意味です。
また、res1$score[,1] で各点が方向ベクトルの何倍なのかを得ることができます。

> res1$score[,1]
[1] -0.05176209 -1.59257228 2.12906814 -0.14387618 -1.16726426 1.28359077
[7] 1.51268231 -1.94956546 -1.39275710 1.37245617

c1 の値を確認してみると(向きは逆ですが)正しい答えが得られていることがわかります。

> c1
[1] 0.05176209 1.59257228 -2.12906814 0.14387618 1.16726426 -1.28359077
[7] -1.51268231 1.94956546 1.39275710 -1.37245617

これを一般化して、n 次元空間の点を m 本の方向ベクトルの線形和で生成したときも、点の座標の表を主成分分析すれば、各点について m 個の成分に情報を削減することができます。
ただし、方向ベクトルが単位ベクトルでなかったり、方向ベクトルが直交していなかったり、成分ベクトルの平均が0でない場合には、始めに与えた成分とは異なる m 次元のデータが得られます。

主成分分析

ここまでは説明のために方向ベクトルの線形和でデータを生成してきましたが、主成分分析は、データが実際にはどう作られたかはさておき、与えられた成分をうまいこと少数の方向ベクトルの線形和に変換するための手法です。

座標変換(といっていいのかわかりませんが)の中心はデータの標本平均です。
最初の一本目の方向は、その方向に全てのデータを射影したときに、その方向上での標本分散が最大になるものを選びます。
分散がなるべく大きい方が、その方向ではデータがばらついている=その方向でデータの差異を説明し易い、ということになります。
二本目は、一本目に直交する方向の中で、同じく全てのデータをその方向に射影したときに方向上での標本分散が最大になるものを選びます。
以下同様に分散を用いて必要な本数だけ方向を選んでいきます。
なお、i 番目の方向(の各係数)を第 i 主成分といい、データが主成分の線形和の中でその方向に何倍されているかを第 i 主成分得点といいます。

princomp の結果を summary に与えたときの各列の値は各方向に関する情報を表しています。
左から第 1 主成分、第 2 主成分、となっています。
Standard deviation はその方向にデータを射影したときの標準偏差です。
Proportion of Variance (寄与率)は全ての主成分に関する分散の和のうち、それぞれの主成分の分散の大きさがどれくらいかを表す指標です。
Cumulative Proportion (累積寄与率)は第 1 主成分からその主成分までの分散の和が全体に対してどれくらいの大きさかを表しています。
もし第 1 主成分の寄与率が 1 であれば、データは直線上に載っていることになります。
もし第 m 主成分の累積寄与率が 1 であれば、わざわざ元の n 次元の全ての成分を見なくても、m 次元の情報でデータを表せることになります。
実際に使用するときには、先頭の少ない主成分(第 1, 2, 3 くらい)の累積寄与率が十分高ければそれ以降は無視してしまいます。
よくある使い方としては、第 1 主成分得点と第 2 主成分得点を使って二次元散布図にプロットして可視化したりします。

ちなみに、主成分を求める問題はデータの分散共分散行列の固有ベクトルを求める問題と同等だそうです。