728x90
반응형

지금까지 행렬 생성과 행렬에 대한 기본적인 조작, 데이터 접근, 행렬 연산 등에 대해 학습해 보았다.

이번에는 포스트에선 역행렬, 가운데 행렬과 같은 약간 독특한 행렬들에 대해 학습해보자.

 

역행렬(Inverse Matrix)

  • 역행렬은 행렬의 역수라고 할 수 있으며, 행렬 A와 곱했을 때 단위 행렬 E가 나오게 하는 행렬을 A의 역행렬이라고 한다.
  • 역행렬은 정방행렬(n x n)에 대해서만 구할 수 있다. 장방행렬(n x m)에 대해서는 구할 수 없다.
  • solve()
    : 수식 A %*% X = B에서 X인 행렬을 구한다. 즉, A와 행렬곱 하여 B가 만들어지게 하는 행렬 X를 구한다.
  • 주요 Parameter
    : solve(A, B, ...)
    B의 자리를 공란으로 넣는다면, A의 역행렬을 구한다.
vt3 = c(4, 2, 3, 0, 1, 0, 2, 3, 0, 2, 1, 4, 0, 2, 1, 3)
mat3 = matrix(vt3, nrow = 4, byrow = TRUE)
mat3
##      [,1] [,2] [,3] [,4]
## [1,]    4    2    3    0
## [2,]    1    0    2    3
## [3,]    0    2    1    4
## [4,]    0    2    1    3
solve(mat3)
##             [,1]       [,2]  [,3]       [,4]
## [1,]  0.33333333 -0.3333333  2.00 -2.3333333
## [2,]  0.08333333 -0.3333333 -0.25  0.6666667
## [3,] -0.16666667  0.6666667 -2.50  2.6666667
## [4,]  0.00000000  0.0000000  1.00 -1.0000000

 

 

 

전치행렬(Transpose Matrix)

  • R(기초) 행렬(Matrix)(2부)에서 잠깐 다뤘던 전치행렬에 대해서 다시 한번 정리하겠다.
  • m*n 행렬의 행과 열을 서로 바꾼 n*m 행렬로 만든 것을 전치 행렬이라고 한다.
  • 주대각선(Main Diagonal)을 기준으로 하여 뒤집은 것을 가리킨다.
    ※ (1,1), (2,2), (3,3).... 과 같이 행과 열의 값이 같은 행렬의 가운데 부분을 주대각선(대각성분)이라 한다.
  • t()
    : 전치행렬로 만든다.

※ 대각성분(주대각선)인 (1,1), (2,2), (3,3)을 기준으로 뒤집은 것이 전치 행렬이다.

mat <- matrix(c(1:12), nrow = 4, byrow = TRUE)
mat
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
## [4,]   10   11   12
t(mat)
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12

 

 

 

대칭행렬(Symmetric Matrix)

  • 대각성분을 중심으로 대칭인 정방행렬(n*n)을 가리킨다.
  • 대각성분을 중심으로 대칭이므로, 원래 행렬과 전치행렬은 동일하다.
  • 대칭행렬을 만들고 싶다면, 일반 행렬을 생성하고, 상삼각행렬 혹은 하삼각행렬의 위치에 대하여, 그 전치행렬의 값을 덮어 씌우면 된다.
    (무슨 말인지 모르겠지만, 실습을 하며 천천히 따라와보면 이해하게 될 것이다.)
# 대칭행렬을 만들어보자
mat = matrix(c(1:16), nrow = 4, byrow = TRUE)
mat
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
## [4,]   13   14   15   16
  •  c(1:16)으로 1~16까지 값이 들어간 벡터로, 정방행렬(4*4)을 만들었다.
# 하삼각행렬의 값들을 가져와보자
lower.tri(mat, diag = FALSE)
##       [,1]  [,2]  [,3]  [,4]
## [1,] FALSE FALSE FALSE FALSE
## [2,]  TRUE FALSE FALSE FALSE
## [3,]  TRUE  TRUE FALSE FALSE
## [4,]  TRUE  TRUE  TRUE FALSE
  •  lower.tri()는 하삼각행렬을 만들 때 사용하는 함수로, 뒤에서 다시 한번 다루겠지만, 가운데 성분을 기준으로하여, 아랫쪽을 TRUE로 Masking한다.
    (상삼각행렬을 쓰는 경우엔, upper.tri()를 쓰면 되며, 방법은 동일하다.)
  •  lower.tri()의 parameter인 diag는 대각성분을 포함할 것인지 여부이다.
mat[lower.tri(mat, diag = FALSE)]
## [1]  5  9 13 10 14 15
  • 벡터, 행렬에서 Indexing을 할 때, 우리는 대괄호를 사용하여 가져왔었는데, 이 대괄호는 TRUE로 Masking된 값들을 가져오는 것이다.
# 전치행렬에 대한 하삼각행렬의 위치의 값을 본 행렬의 하삼각행렬 위치에 넣도록 하자.
mat[lower.tri(mat, diag = FALSE)] <- t(mat)[lower.tri(mat, diag = FALSE)]
mat
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    2    6    7    8
## [3,]    3    7   11   12
## [4,]    4    8   12   16
  • 조금 복잡해보이지만, 원리는 되게 단순하다.
  • 대칭행렬은 대각성분을 중심으로 대칭인 행렬이고, 전치행렬은 대각성분을 중심으로 반전된 행렬이다.
  • 즉, 원래의 행렬의 하삼각행렬(or 상삼각행렬)에 전치행렬의 하삼각행렬(or 상삼각행렬)의 위치의 값을 넣으면, 대칭행렬이 만들어지는 것이다.
  • 이를 더 풀어서 써보면 가운데 성분 아래(하삼각행렬의 위치 = TRUE로 Masking 된 곳)에 가운데 성분 위의 값을 가운데 성분을 중심으로 뒤집어서(전치 행렬) 가운데 성분 아래에 그대로 넣었다고 생각하면 된다.

 

 

 

대각 행렬(Diagonal Matrix)

  • 대각행렬은 대칭행렬과 비슷해보이지만, 생성 난이도는 보다 쉬운 행렬이다.
  • 대각행렬은 정방행렬(n*n)에서 대각성분을 제외한 모든 값이 0인 경우를 말한다.
  • diag()
    : 행렬의 대각성분을 가지고 오거나, 대각성분에 다른 값을 넣을 수 있게 해주는 함수, diag(Vector)를 하는 경우, 대각행렬이 생성된다.
  • 항등행렬(Identity Matrix)는 대각성분이 1이고 나머지 원소는 0인 행렬이므로, 대각성분을 모두 1로 생성하면 된다.
# 대각행렬을 만들어보자.
diag(c(1:5))
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    0    0    0    0
## [2,]    0    2    0    0    0
## [3,]    0    0    3    0    0
## [4,]    0    0    0    4    0
## [5,]    0    0    0    0    5
  • 가운데 성분을 제외하고 모두 0인 대각행렬을 만들어보았다.
# 대각성분을 가지고 와보자
mat <- matrix(c(1:16), nrow = 4)
mat
##      [,1] [,2] [,3] [,4]
## [1,]    1    5    9   13
## [2,]    2    6   10   14
## [3,]    3    7   11   15
## [4,]    4    8   12   16
diag(mat)
## [1]  1  6 11 16
  • diag() 함수를 이용하면, 행렬의 대각성분만 벡터로 가지고 올 수 있다.
# 대각성분의 원소를 모두 0으로 만들자
diag(mat) <- 0
mat
##      [,1] [,2] [,3] [,4]
## [1,]    0    5    9   13
## [2,]    2    0   10   14
## [3,]    3    7    0   15
## [4,]    4    8   12    0
  • 행렬의 대각성분에 스칼라 값을 넣어서 대각성분이 0인 행렬을 만들어보았다.
  • 대칭행렬 만들기와 대각성분을 0으로 만들기를 조합하여 코드를 짜면 대칭행렬이면서 대각성분이 0인 행렬을 만들 수 있다.

 

 

 

하삼각행렬(Lower Triangular Matrix)과 상삼각행렬(Upper Triangular Matrix)

  • 하삼각행렬은 대각성분을 중심으로, 그 윗 부분이 모두 0인 정방행렬을 말한다.
  • 상삼각행렬은 대각성분을 중심으로, 그 아랫 부분이 모두 0인 정방행렬을 말한다.
  • lower.tri()
    : 행렬의 가운데 성분을 기점으로(가운데 성분 포함 가능), 아랫 부분을 TRUE로 Masking하는 함수
  • upper.tri()
    : 행렬의 가운데 성분을 기점으로(가운데 성분 포함 가능), 윗 부분을 TRUE로 Masking하는 함수
  • 상삼각행렬은 대각성분을 중심으로, 아랫 부분이 0이므로, lower.tri()함수를 이용해 대각성분 아래쪽을 indexing하여 0을 집어넣으면 된다.
  • 하삼각행렬은 대각성분을 중심으로, 윗 부분이 0이므로, upper.tri()함수를 이용해 대각성분 위쪽을 indexing하여 0을 집어넣으면 된다.
# 상삼각행렬을 만들어보자.
mat = matrix(c(1:16), 4)
lower.tri(mat, diag = FALSE)
  • diag = FALSE 로 Parameter를 부여하여, 가운데 성분은 Masking하지 않도록 하자.
##       [,1]  [,2]  [,3]  [,4]
## [1,] FALSE FALSE FALSE FALSE
## [2,]  TRUE FALSE FALSE FALSE
## [3,]  TRUE  TRUE FALSE FALSE
## [4,]  TRUE  TRUE  TRUE FALSE
mat[lower.tri(mat, diag = FALSE)] <- 0
mat
  • 선택된 가운데 성분의 아랫부분에 0을 넣어서 상삼각행렬을 만들었다.
##      [,1] [,2] [,3] [,4]
## [1,]    1    5    9   13
## [2,]    0    6   10   14
## [3,]    0    0   11   15
## [4,]    0    0    0   16
# 하삼각행렬을 만들어보자.
mat = matrix(c(1:16), 4)
upper.tri(mat, diag = FALSE)
##       [,1]  [,2]  [,3]  [,4]
## [1,] FALSE  TRUE  TRUE  TRUE
## [2,] FALSE FALSE  TRUE  TRUE
## [3,] FALSE FALSE FALSE  TRUE
## [4,] FALSE FALSE FALSE FALSE
mat[upper.tri(mat, diag = FALSE)] <- 0
mat
##      [,1] [,2] [,3] [,4]
## [1,]    1    0    0    0
## [2,]    2    6    0    0
## [3,]    3    7   11    0
## [4,]    4    8   12   16

 

 

자, 지금까지 역행렬, 전치행렬, 대각행렬, 대칭행렬, 상삼각행렬, 하삼각행렬에 대해 알아보았다. 행렬은 이 것보다 훨씬 심도 깊은 분야기 때문에, R의 기초인 데이터 타입 공부에선 기본적으로 알아야하는 부분만 짚고 넘어가도록 하겠다.

다음 포스트에선 배열(Array)에 대해 학습해보도록 하겠다.

728x90
반응형

'R > Basic' 카테고리의 다른 글

R(기초) 데이터프레임(Data Frame)(1부)  (0) 2020.06.21
R(기초) 배열(Array)  (0) 2020.06.19
R(기초) 행렬(Matrix)(2부)  (0) 2020.06.19
R(기초) 행렬(Matrix)(1부)  (0) 2020.06.18
R(기초) 연산자와 변수 타입  (0) 2020.06.18

+ Recent posts