Rで見る主成分分析と特異値分解の関係

多次元主成分分析を行うにあたって、主成分分析と特異値分解の関係を復習してみた。

まず、データを作成する。

# x:1000個の正規分布N(0, 0.2)に従う乱数
# y : xを3倍し、そこにN(0, 0.3)に従うノイズを加えたもの

# x2, y2: x, yそれぞれについて平均を引いて標準偏差で割って標準化したもの

# x3, y3: x2, y2を大きさ1になるように規格化

# z2: cbind(x3, y3)で作成した1000 x 2の行列

 

x <- rnorm(1000, 0, 0.2)
y <- 3*x + rnorm(1000, 0, 0.3)
mx <- mean(x)
sdx <- sd(x)
my <- mean(y)
sdy <- sd(y)
x2 <- (x - mx)/sdx
y2 <- (y - my)/sdy

x2 %*% x2
      [,1]
[1,] 999

y2 %*% y2
     [,1]
[1,] 999


x3 <- x2/sqrt(999)
y3 <- y2/sqrt(999)

z2 <- cbind(x3, y3)

plot(x3, y3)

で確認できるように、第一主成分だけでほぼ説明できるデータである。

 

z2を特異値分解する。

# w2: z2のSVD
# w2$u 1000 x 2 主成分得点行列

 

w2 <- svd(z2)

w2の中身を見る。

str(w2)
List of 3
$ d: num [1:2] 1.376 0.327
$ u: num [1:1000, 1:2] 0.00732 0.01653 -0.00181 0.03669 -0.02696 ...
$ v: num [1:2, 1:2] 0.707 0.707 0.707 -0.707

 

# 主成分と元データの相関係数
cor(w2$u[,1], x3)
[1] 0.972893
cor(w2$u[,1], y3)
[1] 0.972893
cor(w2$u[,2], x3)
[1] 0.2312559
cor(w2$u[,2], y3)
[1] -0.2312559

 

# w2$uの直交性を利用して、データからw2$uを消して、因子負荷行列を作成
t(w2$u) %*% z2
                   x3              y3
[1,] 0.9728930 0.9728930
[2,] 0.2312559 -0.2312559

 

# 特異値の対角行列diad(w2$d)とt(w2$v)から、因子負荷行列を作成
diag(w2$d) %*% t(w2$v)
      [,1]                        [,2]
[1,] 0.9728930 0.9728930
[2,] 0.2312559 -0.2312559

 

diag(w2$d) %*% t(w2$v) 2 x 2 因子負荷行列
因子負荷は主成分と元データの相関であることが確認できる。

 

主成分軸の表現
第一主成分のプロット
a <- seq(-0.2,0.2, 0.001)
b1 <- a * w2$v[1,1]
plot(x3, y3, xlim=c(-0.2, 0.2), ylim=c(-0.1, 0.15))
par(new=T)
plot(b1, b2, xlim=c(-0.2, 0.2), ylim=c(-0.1, 0.15), ty='l', col=rgb(1,0,0))b2 <- a * w2$v[2,1]

 

主成分分析では、w2$vが相関係数行列の固有値問題を解いた場合の
固有ベクトルとして得られる。
vを主成分得点とした時の負荷行列を計算 
これが元データを回転させた主成分軸上の座標を与える
e <- w2$u %*% diag(w2$d)
max(e[,1])
[1] 0.174004
min(e[,1])
[1] -0.1284722
max(e[,2])
[1] 0.03881079
min(e[,2])
[1] -0.02979512
plot(e[,1],e[,2],xlim=c(-0.13,0.18), ylim=c(-0.13,0.18))

直交性を利用して、t(w2$v)を打ち消して、因子負荷行列を求める
上と同じプロットが得られる。
d <- z2 %*% w2$v
max(d[,1])
[1] 0.174004

max(d[,2])
[1] 0.03881079
min(d[,1])
[1] -0.1284722
min(d[,2])
[1] -0.02979512
plot(d[,1],d[,2],xlim=c(-0.13,0.18), ylim=c(-0.13,0.18))

因子負荷行列が主成分軸上での座標を表している。