Summary

굉장히 큰 행렬 A, B 가 있다. random sampling 을 이용해서 AB와 근사한 행렬이 나옴을 개략적 단계를 통해서 확인한다.

주의사항: 전체적인 과정이나 수식에 대한 이해도가 낮아서, 원하는 결과가 안나온다. 원인이 무엇인지 좀더 살펴봐야 한다.

A, B 행렬 생성

# A 는 5x3 행렬, B는 3x2 행렬
A <- matrix(c(10, 7, 7, 5, 4, 3, 2, 1, 1, 1, 2, 1, 3, 4, 5), nrow = 5, byrow=F)
dim(A)
## [1] 5 3
m <- nrow(A) # 행 갯수
n <- ncol(A) # 컬럼 갯수

B <- matrix(c(7, 8, 9, 2, 1, 3), nrow= 3, byrow=F)
dim(B)
## [1] 3 2
p <- ncol(B) # 컬럼 갯수

AB 곱셈 결과 생성

AB 를 곱하면 5x2 행렬이 생성된다.

AB <- A %*% B

A, B 의 norm 계산

A의 컬럼에 대해서, B의 행에 대해서 norm 을 계산한다.

# A의 각 열에 대한 norm 을 계산한다.
my_norm <- function(x)
{
  sqrt(sum(x^2))
}

A_norm <- apply(A, 2, my_norm) # 2: 컬럼 기준으로 norm 계산
A_norm
## [1] 15.459625  4.000000  7.416198
B_norm <- apply(B, 1, my_norm) # 1: 행 기준으로 norm 계산
B_norm
## [1] 7.280110 8.062258 9.486833

Pj 확률 계산

A 의 각 컬럼을 선택하는 확률을 구한다.

# || aj || * || bjT || 의 합을 구한다.
C <- sum(A_norm * B_norm)

# Aj 에 대한 선택확률 Pj 를 구한다.
A_prob <- (A_norm * B_norm) / C
A_prob
## [1] 0.5231056 0.1498888 0.3270055

random sampling 수행

A의 선택확률에 따라서 샘플 2개를 구한다.

# 1~n 사이에 size=2 개 만큼 선택하는데, 확률은 prob 을 따른다.
s <- sample(x=1:n, size=2, prob=A_prob) 
s
## [1] 1 3

AB 의 근사치 계산

AB 에 대한 근사치를 구한다.

# rank 1 행렬을 구한다.
my_rank1 <- function(aj, bj)
{
  aj %*% t(bj)
}


#A1 <- A[,1]
#B1 <- B[1,]
#A1 %*% t(B1)
#temp <- A[,s] %*% B[s,]
#temp / A_prob[1]

# 근사치 행렬 초기화
AB_prox <- matrix(rep(0, times=10), nrow=5, byrow=T)

# 샘플수 만큼 루프 돌면서 랭크1 행렬을 계산한다.
for (j in s)
{
  aj <- A[,j]
  bj <- B[j,]
  
  ab_rank1 <- my_rank1(aj, bj) # rank 1 행렬 생성
  Pj <- A_prob[j] # A의 j 열이 선택될 확률
  
  ab_rank1 <- ab_rank1 *  1 / (Pj * 2)
  AB_prox <- AB_prox + ab_rank1
}

AB와 AB 근사치 비교

생각하는 결과와 다르다. 원인은 잘 모르겠다.

AB
##      [,1] [,2]
## [1,]  112   29
## [2,]   74   19
## [3,]   84   24
## [4,]   79   23
## [5,]   81   24
AB_prox
##          [,1]     [,2]
## [1,] 94.43056 28.29075
## [2,] 60.59690 17.96870
## [3,] 88.11937 27.14285
## [4,] 88.49898 27.90661
## [5,] 95.56941 30.58203