굉장히 큰 행렬 A, B 가 있다. random sampling 을 이용해서 AB와 근사한 행렬이 나옴을 개략적 단계를 통해서 확인한다.
주의사항: 전체적인 과정이나 수식에 대한 이해도가 낮아서, 원하는 결과가 안나온다. 원인이 무엇인지 좀더 살펴봐야 한다.
# 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 를 곱하면 5x2 행렬이 생성된다.
AB <- A %*% B
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
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
A의 선택확률에 따라서 샘플 2개를 구한다.
# 1~n 사이에 size=2 개 만큼 선택하는데, 확률은 prob 을 따른다.
s <- sample(x=1:n, size=2, prob=A_prob)
s
## [1] 1 3
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
## [,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