Summary

본 내용은 MIT 18.065 강의 34 번의 일부 내용정리입니다. 교재는 page 257 입니다. 자세한 내용은 해당 강의를 참조하세요.

Source: https://ocw.mit.edu/courses/mathematics/18-065-matrix-methods-in-data-analysis-signal-processing-and-machine-learning-spring-2018/video-lectures/lecture-34-distance-matrices-procrustes-problem-first-project/

SVD 응용을 보자. 벡터 \(x_1,,,x_n\)\(y_1,,,y_n\) 이 있다. 어떤 직교행렬 Q 가, y 하고 곱해서 가장 가까운 x 를 구할 수 있을까?

여기서는 translation 과 rescaling 을 허용하지 않는 제약된 상황이라고 가정하자. 이 문제를 Orthogonal Procrustes Problem 이라고 부른다.

해결하는 방법은 아래와 같다.

  1. 행렬 X와 Y를 구축한다.
  2. \(Y^TX\) 를 구하고
  3. 특이값 분해(singular value decomposition)를 수행한다. \(Y^TX = U \Sigma V^T\)
  4. 직교 행렬 \(Q = V^TU\)\(||X - YQ||^2_F\) 를 최소화한다.

실습

아래와 같이 4개의 도형에 대한 행렬을 준비한다. 그리고 어떤 행렬이 서로 가장 유사한지를 구한다. 회전만을 고려하며, 반영(reflection) 은 고려하지 않는다.

결론은, B와 C가 제일 유사하다.

행렬

행렬

좌표 그림은 https://www.geogebra.org/ 를 이용했습니다.

library(matrixcalc)

# 두 개 행렬을 입력받아, 얼마나 유사한지 정보를 frobenius norm 으로 반환한다.
my_procrustes_similar <- function(X1, Y1) {
  
  # 평균을 빼서 중앙으로 맞춘다.
  X <- X1 - rowMeans(X1)
  Y <- Y1 - rowMeans(Y1)
  
  # Y^T X 를 구한다.
  YTX <- t(Y) %*% X
  
  # YTX 의 SVD 를 구한다.
  my_svd <- svd(YTX)
  
  U <- my_svd$u
  V <- my_svd$v
  
  # Q를 구한다.
  Q <- U %*% t(V)
  
  # X - YQ 를 구한다.
  result <- X - (Y %*% Q)

  # 성분 제곱합에 대한 제곱근을 구한다.
  round(frobenius.norm(result), 2)
}

# 행렬을 구축한다.
A <- matrix(c(1, 3, 3, 3, 3, 4), nrow=2, byrow=TRUE)
B <- matrix(c(4, 4, 6, 4, 3, 3), nrow=2, byrow=TRUE)
C <- matrix(c(1, 3, 3, 2, 2, 1), nrow=2, byrow=TRUE)
D <- matrix(c(4, 6, 5, 2, 2, 1), nrow=2, byrow=TRUE)


my_procrustes_similar(A, B) # A와 B를 비교한다.
## [1] 0.75
my_procrustes_similar(A, C) # A와 C를 비교한다.
## [1] 0.75
my_procrustes_similar(A, D) # A와 D를 비교한다.
## [1] 0.43
my_procrustes_similar(B, C) # B와 C를 비교한다.
## [1] 0