R prcomp での主成分分析結果から元データを復元する
普通はこんなことやる必要ないですが、、、主成分分析 prcomp
関数の結果のみを引数にして、元データ込みの処理を行う関数がどうしても書きたかったので。
# 元データ head(iris) # Sepal.Length Sepal.Width Petal.Length Petal.Width Species # 1 5.1 3.5 1.4 0.2 setosa # 2 4.9 3.0 1.4 0.2 setosa # 3 4.7 3.2 1.3 0.2 setosa # 4 4.6 3.1 1.5 0.2 setosa # 5 5.0 3.6 1.4 0.2 setosa # 6 5.4 3.9 1.7 0.4 setosa # 数値列のみにフィルタ df <- iris[c(1, 2, 3, 4)]
このデータに対して主成分分析を行い、得られた結果から元データを復元したい。
主成分分析では元データを分散が最大になる方向に回転させたものが主成分得点、回転を定義する行列が主成分(固有ベクトル)になっているため、主成分得点を主成分(固有ベクトル)と逆に回転すれば元の方向に戻る。また、prcomp
デフォルトでは center = TRUE
が指定されており、元データの平均値を 0 にする標準化が行われているので、こちらも逆の処理をすれば元データに戻せる。
# 主成分分析実行 pca.result <- prcomp(df) str(pca.result) # List of 5 # $ sdev : num [1:4] 2.056 0.493 0.28 0.154 # $ rotation: num [1:4, 1:4] 0.3614 -0.0845 0.8567 0.3583 -0.6566 ... # ..- attr(*, "dimnames")=List of 2 # .. ..$ : chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" # .. ..$ : chr [1:4] "PC1" "PC2" "PC3" "PC4" # $ center : Named num [1:4] 5.84 3.06 3.76 1.2 # ..- attr(*, "names")= chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" # $ scale : logi FALSE # $ x : num [1:150, 1:4] -2.68 -2.71 -2.89 -2.75 -2.73 ... # ..- attr(*, "dimnames")=List of 2 # .. ..$ : NULL # .. ..$ : chr [1:4] "PC1" "PC2" "PC3" "PC4" # - attr(*, "class")= chr "prcomp" # 主成分と逆方向に回転 original <- pca.result$x %*% t(pca.result$rotation) # 平均値の標準化を元に戻す original <- scale(original, center = -pca.result$center, scale = FALSE) head(original) # Sepal.Length Sepal.Width Petal.Length Petal.Width # [1,] 5.1 3.5 1.4 0.2 # [2,] 4.9 3.0 1.4 0.2 # [3,] 4.7 3.2 1.3 0.2 # [4,] 4.6 3.1 1.5 0.2 # [5,] 5.0 3.6 1.4 0.2 # [6,] 5.4 3.9 1.7 0.4
prcomp(scale=TRUE)
で標準偏差も標準化して主成分分析した場合は、平均値を戻す前に標準偏差を戻す。
# 主成分分析実行 pca.result <- prcomp(df, scale = TRUE) # 主成分と逆方向に回転 original <- pca.result$x %*% t(pca.result$rotation) # 標準偏差の標準化を元に戻す original <- scale(original, center = FALSE, scale = 1 / pca.result$scale) # 平均値の標準化を元に戻す original <- scale(original, center = -pca.result$center, scale = FALSE) head(original) # Sepal.Length Sepal.Width Petal.Length Petal.Width # [1,] 5.1 3.5 1.4 0.2 # [2,] 4.9 3.0 1.4 0.2 # [3,] 4.7 3.2 1.3 0.2 # [4,] 4.6 3.1 1.5 0.2 # [5,] 5.0 3.6 1.4 0.2 # [6,] 5.4 3.9 1.7 0.4