2.5 행렬(matrix)
행렬의 정의
- 동일한 데이터 타입의 원소로 구성된 2차원 데이터 구조
- \(n \times 1\) 차원 벡터 \(p\)개로 묶여진 데이터 덩어리 \(\rightarrow\) \(n \times p\) 행렬로 명칭함
- 행렬의 형태
\[\begin{bmatrix} x_{11} & x_{12} & \cdots & x_{1p} \\ x_{21} & x_{22} & \cdots & x_{2p} \\ \vdots & \vdots & \cdots & \vdots \\ x_{n1} & x_{n2} & \cdots & x_{np} \end{bmatrix} \]
- R에서 행렬은 동일한 유형의 데이터 타입으로 구성 가능 \(\rightarrow\) 첫 번째 행은 숫자형, 두 번째 행은 문자열로 입력해도 행렬을 만들 수 있지만, 표현력이 더 높은 문자형 행렬 반환
- 행렬의 내부 저장공간은 “열 우선 배열”
- 행렬 생성을 위한 R 함수는
matrix()
함수이고 사용 형태는 아래와 같음
# matrix(): 행렬 생성 함수
# 상세 내용은 help(matrix)를 통해 확인
matrix(data, # 행렬을 생성할 데이터 벡터
# 행의 개수 (정수)
nrow, # 열의 개수 (정수)
ncol, # TRUE: 행 우선, FALSE: 열 우선
byrow, # default = FALSE
# 행렬읠 각 차원에 부여할 이름 (리스트)
dimnames )
- 행렬 생성 예시
# byrow = FALSE
<- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 3, ncol = 3)
x x
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
# byrow = TRUE
<- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 3, ncol = 3, byrow = T)
x x
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
- 행의 개수(
nrow
)나 열의 개수(ncol
)로 나머지를 추정 가능하다면 둘 중 어떤 인수도 생략 가능
<- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), ncol = 3)
x x
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
<- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 3)
x x
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
nrow
\(\times\)ncol
이 입력한 데이터(벡터)의 길이보다 작거나 큰 경우
# length(x) < nrow * ncol 인 경우
# nrow * ncol에 해당하는 길이 만큼
# x의 원소를 사용해 행렬 생성
<- c(1, 2, 3, 4, 5, 6, 7, 8, 9)
x <- matrix(x, nrow = 3, ncol = 4) y
Warning in matrix(x, nrow = 3, ncol = 4): 데이터의 길이[9]가 열의 개수[4]의
배수가 되지 않습니다
y
[,1] [,2] [,3] [,4]
[1,] 1 4 7 1
[2,] 2 5 8 2
[3,] 3 6 9 3
# length(x) > nrow * ncol 인 경우
# x의 첫 번쨰 원소부터 초과하는 만큼
# x 원소의 값을 재사용
<- matrix(x, nrow = 2, ncol = 3) z
Warning in matrix(x, nrow = 2, ncol = 3): 데이터의 길이[9]가 행의 개수[2]의
배수가 되지 않습니다
z
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
- 행렬 구성 시 길이에 대한 약수가 아닌 값을
nrow
또는ncol
의 인수로 받은 경우
# x (length=9)로 행렬 생성 시 nrow=4 를
# 인수로 입력한 경우
<- matrix(x, nrow = 4) h
Warning in matrix(x, nrow = 4): 데이터의 길이[9]가 행의 개수[4]의 배수가 되지
않습니다
h
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 1
[3,] 3 7 2
[4,] 4 8 3
# x (length=9)로 행렬 생성 시 ncol=2 만
# 인수로 입력한 경우
<- matrix(x, nrow = 2) h
Warning in matrix(x, nrow = 2): 데이터의 길이[9]가 행의 개수[2]의 배수가 되지
않습니다
h
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 1
2.5.1 행렬의 연산
- 선형대수(linear algebra)에서 배우는 행렬-스칼라, 행렬-행렬 간 연산 가능
행렬-스칼라 연산
합 연산: 스칼라가 자동적으로 행렬의 차원에 맞춰서 재사용
\[\begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{bmatrix} + 4 = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{bmatrix} + \begin{bmatrix} 4 & 4 & 4 \\ 4 & 4 & 4 \\ 4 & 4 & 4 \end{bmatrix} = \begin{bmatrix} 5 & 6 & 7 \\ 8 & 9 & 10 \\ 11 & 12 & 13 \end{bmatrix} \]
<-matrix(1:9, 3, 3, byrow = T)
x + 4 x
[,1] [,2] [,3]
[1,] 5 6 7
[2,] 8 9 10
[3,] 11 12 13
곱 연산
\[\begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{bmatrix} \times 4 = \begin{bmatrix} 4 & 8 & 12 \\ 16 & 20 & 24 \\ 28 & 32 & 36 \end{bmatrix} \]
*4 x
[,1] [,2] [,3]
[1,] 4 8 12
[2,] 16 20 24
[3,] 28 32 36
행렬-행렬 연산
- 행렬 간 연산에서 스칼라 연산(일반 연산)과 다른 점은 차원이 개입
행렬 간 합(차)
- 두 행렬의 동일 차원 간 합 연산 수행(
+
또는-
연산자 사용)
\[\begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{bmatrix} + \begin{bmatrix} 1 & -1 & ~~~2 \\ 3 & ~~~2 & ~~~4 \\ -6 & ~~~3 & -7 \end{bmatrix} = \begin{bmatrix} 2 & 1 & 5 \\ 7 & 7 & 10 \\ 1 & 11 & 2 \end{bmatrix} \]
<- matrix(1:9, 3, 3, byrow = T)
x <- matrix(c(1, 3, -6, -1, 2, 3, 2, 4, -7), ncol = 3)
y + y x
[,1] [,2] [,3]
[1,] 2 1 5
[2,] 7 7 10
[3,] 1 11 2
행렬 곱/나누기(elementwise product/division)
- 연산자
*
또는/
사용
\[\begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{bmatrix} * \begin{bmatrix} ~~~1 & -1 & ~~~2 \\ ~~~3 & ~~~2 & ~~~4 \\ -6 & ~~~3 & -7 \end{bmatrix} = \begin{bmatrix} ~~~~~ 1 & -2 & ~~~~6 \\ ~~~ 12 & ~10 & ~~~24 \\ -42 & ~24 & -63 \end{bmatrix} \]
* y x
[,1] [,2] [,3]
[1,] 1 -2 6
[2,] 12 10 24
[3,] -42 24 -63
- 행렬-행렬 합(차) 또는 곱(나누기) 연산 시 행렬의 열단위 원소가 재사용되지 않음
동일 차원 간 연산만 가능!!
<- y[, 1:2] # y 행렬에서 1-2 번째 열 추출
z # 3 by 2 행렬 z
[,1] [,2]
[1,] 1 -1
[2,] 3 2
[3,] -6 3
+ z x
Error in x + z: 배열의 크기가 올바르지 않습니다
* z x
Error in x * z: 배열의 크기가 올바르지 않습니다
/ z x
Error in x/z: 배열의 크기가 올바르지 않습니다
행렬 간 곱(matrix product)
- 두 행렬 \(\mathrm{\mathbf X}_{n\times m}\), \(\mathrm{\mathbf Y}_{m\times k}\) 이 주어졌을 때 두 행렬의 곱(matrix product) \(\mathrm{\mathbf Z} = \mathrm{\mathbf {X\cdot Y}}\)는 \(n \times k\) 행렬이고 \(\mathrm{\mathbf Z}\) 원소 \(z_{ij}\) (\(i={1,\ldots,n}\), \(j={1,\ldots,k}\)) 아래와 같이 정의됨
\[
z_{ij} = \sum_{r=1}^{m}x_{ir}y_{rj},~~~~\forall~\{i, j\}
\] - R에서 위와 같은 연산은 %*%
를 사용
- 예시: 행렬 \(\mathrm{\mathbf X}_{2\times 4}\), \(\mathrm{\mathbf Y}_{4\times 3}\) 이 아래와 같이 주어졌을 때 두 행렬의 곱 \(\mathrm{\mathbf Z}_{2\times 3} = \mathrm{\mathbf{X}}_{2\times 4}\mathrm{\mathbf{Y}}_{4 \times 3}\)는 아래와 같음
\[ \mathrm{\mathbf X}= \begin{bmatrix} 1 &~~~ 1 & -1 & 1 \\ 1 & -1 &~~~ 1 & 1 \end{bmatrix}, ~~~~~ \mathrm{\mathbf{Y}}= \begin{bmatrix} 1 & -2 & -1 \\ 1 &~~~1 &~~~2 \\ 1 &~~~3 &~~~1 \\ 1 &~~~2 &~~~2 \end{bmatrix} \]
\[ \mathrm{\mathbf{Z}} = \mathrm{\mathbf{X}}\mathrm{\mathbf{Y}} = \begin{bmatrix} 1 &~~~ 1 & -1 & 1 \\ 1 & -1 &~~~ 1 & 1 \\ \end{bmatrix} \cdot \begin{bmatrix} 1 & -2 & -1 \\ 1 &~~~1 &~~~2 \\ 1 &~~~3 &~~~1 \\ 1 &~~~2 &~~~2 \end{bmatrix} = \begin{bmatrix} 2 & -2 & 2 \\ 2 &~~~2 & 0 \end{bmatrix} \]
<- matrix(c(1,1,1,-1,-1,1,1,1), nrow = 2, ncol = 4)
X <- matrix(c(1,1,1,1, -2, 1, 3, 2, -1, 2, 1, 2), nrow = 4, ncol = 3)
Y <- X %*% Y
Z Z
[,1] [,2] [,3]
[1,] 2 -2 2
[2,] 2 2 0
행렬-벡터 연산
- 행렬 \(\mathrm{\mathbf{X}}\)의 행 길이와 벡터 \(\mathrm{\mathbf y}\)의 길이가 같은 경우 \(\rightarrow\) \(\mathrm{\mathbf y}\)를 열 단위로 재사용
\[\mathrm{\mathbf{X}} = \begin{bmatrix} 1 & 2 & 4\\ 1 & 3 & 2\\ 1 & 2 & 1 \end{bmatrix}, ~~~~~ \mathrm{\mathbf y} = [20, 18, 23]^T \]
\[\mathrm{\mathbf{X}} + \mathrm{\mathbf{y}} = \begin{bmatrix} 1 & 2 & 4\\ 1 & 3 & 2\\ 1 & 2 & 1 \end{bmatrix} + \begin{bmatrix} 20 & 20 & 20\\ 18 & 18 & 18\\ 23 & 23 & 23 \end{bmatrix} = \begin{bmatrix} 21 & 22 & 24\\ 19 & 21 & 20\\ 24 & 25 & 24 \end{bmatrix} \]
#행렬-벡터 합 연산
# X = 3 by 3 행렬; y = 3 by 1 벡터
<- c(1, 1, 1, 2, 3, 2, 4, 2, 1)
x <- matrix(x, nrow = 3)
X <- c(20, 18, 23)# 재사용
y
+ y X
[,1] [,2] [,3]
[1,] 21 22 24
[2,] 19 21 20
[3,] 24 25 24
- 행렬 \(\mathrm{\mathbf{X}}\)의 길이와 벡터 \(\mathrm{\mathbf y}\)의 길이가 같은 경우 \(\rightarrow\) 벡터 \(\mathrm{\mathbf y}\)를 자동으로 원소를 행렬(열단위)로 변환
\[\mathrm{\mathbf{X}} = \begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6\\ 7 & 8 & 9 \end{bmatrix}, ~~~~~ \mathrm{\mathbf y} = [1, 2, \ldots, 9]^T \]
\[\mathrm{\mathbf{X}} + \mathrm{\mathbf{y}} = \begin{bmatrix} 1 & 4 & 7\\ 2 & 5 & 8\\ 3 & 6 & 9 \end{bmatrix} + \begin{bmatrix} 1 & 4 & 7\\ 2 & 5 & 8\\ 3 & 6 & 9 \end{bmatrix} = \begin{bmatrix} 2 & 8 & 14\\ 4 & 10 & 16\\ 6 & 12 & 18 \end{bmatrix} \]
#행렬-벡터 합 연산
# 행렬 X의 길이와 벡터 y의 길이가 같은 경우
<- c(1:9); X <- matrix(x, nrow = 3)
x length(X); y <- x
[1] 9
+ y X
[,1] [,2] [,3]
[1,] 2 8 14
[2,] 4 10 16
[3,] 6 12 18
# 길이가 다른 경우
# 1) 행렬 길이보다 큰 경우
<- c(1:10)
y + y X
Warning in X + y: 두 객체의 길이가 서로 배수관계에 있지 않습니다
Error in eval(expr, envir, enclos): dims [product 9]가 객체 [10]의 길이와 일치하지 않습니다
# 1) 행렬 길이의 약수가 아닌 경우
# y 재사용
<- c(1:4)
y + y X
Warning in X + y: 두 객체의 길이가 서로 배수관계에 있지 않습니다
[,1] [,2] [,3]
[1,] 2 8 10
[2,] 4 6 12
[3,] 6 8 10
- 행렬-벡터
%*%
적용 시 벡터는 \(n \times 1\) 행렬로 간주하고 행렬 곱 연산 수행(단 \(\mathrm{\mathbf X}\)와 벡터 \(\mathrm{\mathbf y}\)의 길이는 같아야 함).
\[\mathrm{\mathbf{X}}_{4\times 3} = \begin{bmatrix} 1 & 2 & 1 \\ 1 & 1 & 1 \\ 1 & 3 & 3 \\ 1 & 4 & 4 \end{bmatrix}, ~~~~~ \mathrm{\mathbf y}_{3\times 1} = [7, 6, 8]^T \]
\[\mathrm{\mathbf{X}}\mathrm{\mathbf{y}} = \begin{bmatrix} 1 & 2 & 1 \\ 1 & 1 & 1 \\ 1 & 3 & 3 \\ 1 & 4 & 4 \end{bmatrix} \cdot \begin{bmatrix} 7 \\ 6 \\ 8 \end{bmatrix} = \begin{bmatrix} 27 \\ 21 \\ 49 \\ 63 \end{bmatrix} \]
<- c(1, 1, 1, 1, 2, 1, 3, 4, 1, 1, 3, 4)
x <- c(7, 6, 8)
y <- matrix(x, nrow = 4, ncol = 3)
X %*% y X
[,1]
[1,] 27
[2,] 21
[3,] 49
[4,] 63
행렬의 전치(transpose)
- 전치 행렬(transpose matrix)는 임의의 행렬의 행과 열을 서로 맞바꾼 행렬임
- 행렬 \(\mathrm{\mathbf X}\)의 전치 행렬은 \(\mathrm{\mathbf X}^T\) 또는 \(\mathrm{\mathbf X}'\) 으로 나타냄
- 행렬 \(\mathrm{\mathbf X}\)가 다음과 같이 주어졌을 때 전치 행렬 결과
\[\mathrm{\mathbf{X}} = \begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6 \end{bmatrix} ~~~~~ \mathrm{\mathbf{X}}^T = \begin{bmatrix} 1 & 4 \\ 2 & 5 \\ 3 & 6 \end{bmatrix} \]
- R에서 행렬을 전치시키는 함수는
t()
임
# t(object_name): 전치행렬 반환
<- 1:6
x <- matrix(x, nrow = 2, ncol = 3, byrow = T)
X t(X)
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
# 전치행렬과 행렬 간 곱
<- c(1, 1, 1, 1, 1, 22.3, 23.2, 21.5, 25.3, 28.0)
x <- matrix(x, nrow = 5)
X t(X) %*% X
[,1] [,2]
[1,] 5.0 120.30
[2,] 120.3 2921.87
- 벡터-벡터 곱 연산(
%*%
사용)
\[ \mathrm{\mathbf x} = [1, 2, 3, 4]^T \]
\[\mathrm{\mathbf x}\mathrm{\mathbf x}^T = \begin{bmatrix} 1 \\ 2 \\ 3 \\ 4 \end{bmatrix} \cdot \begin{bmatrix} 1 & 2 & 3 & 4 \end{bmatrix} = \begin{bmatrix} 1 & 2 & 3 & 4 \\ 2 & 4 & 6 & 8 \\ 3 & 6 & 9 & 12 \\ 4 & 8 & 12 & 16 \end{bmatrix} \]
\[\mathrm{\mathbf x}^T\mathrm{\mathbf x} = \begin{bmatrix} 1 & 2 & 3 & 4 \end{bmatrix} \cdot \begin{bmatrix} 1 \\ 2 \\ 3 \\ 4 \end{bmatrix} = 1 + 4 + 9 + 16 = 30 \]
<- 1:4
x %*% t(x) # 행렬 반환 x
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 2 4 6 8
[3,] 3 6 9 12
[4,] 4 8 12 16
t(x) %*% x # 스칼라 반환 x %*% x와 동일 결과 출력
[,1]
[1,] 30
참고: 전치행렬의 성질(통계수학 II 강의내용 참고)
- \((\mathrm{\mathbf{X}}^T)^T = \mathrm{\mathbf{X}}\)
- \((\mathrm{\mathbf{X} + \mathbf{Y}})^T = \mathrm{\mathbf{X}}^T + \mathrm{\mathbf{Y}}^T\)
- \((\mathrm{\mathbf{X}\mathbf{Y}})^T = \mathrm{\mathbf{Y}}^T\mathrm{\mathbf{X}}^T\)
- \((c\mathrm{\mathbf{X}})^T = c\mathrm{\mathbf{X}}^T\), \(c\)는 임의의 상수
역행렬(inverse matrix)
- 행렬의 나눗셈 형태
- 행렬 \(\mathrm{\mathbf{X}}\) 가 \(n \times n\) 정방행렬(square matrix)일 때, 아래를 만족하는 행렬 \(\mathrm{\mathbf{Y}}_{n \times n}\)가 존재하면 \(\mathrm{\mathbf{Y}}\)를 \(\mathrm{\mathbf{X}}\)의 역행렬(inverse matrix)라고 하고 \(\mathrm{\mathbf{X}}^{-1}\)로 나타냄.
\[ \mathrm{\mathbf{X}\mathbf{X}^{-1}} = \mathrm{\mathbf{X}^{-1}\mathbf{X}} = \mathrm{\mathbf{I}}_{n\times n} \]
- 여기서 \(\mathrm{\mathbf{I}}_{n\times n}\)은 대각 원소가 1이고 나머지 원소는 0인 항등 행렬임
- \(2 \times 2\) 행렬의 역행렬은 아래와 같이 구함(\(3\times 3\) 이상 역행렬 구하는 방법은 통계수학 II 강의 참고)
\[\mathrm{\mathbf{X}} = \begin{bmatrix} a & b \\ c & d \end{bmatrix}, ~~~~ \mathrm{\mathbf{X}}^{-1} = \frac{1}{ad - bc} \begin{bmatrix} ~~~d & -b \\ -c &~~~a \end{bmatrix} \]
- R에서 정방 행렬의 역행렬은
solve()
함수를 사용해 구함
# 2 by 2 행렬의 역행렬
<- c(1, 2, 3, 4)
x <- matrix(x, 2)
X solve(X)
[,1] [,2]
[1,] -2 1.5
[2,] 1 -0.5
# 항등 행렬이 나오는지 확인
%*% solve(X) X
[,1] [,2]
[1,] 1 0
[2,] 0 1
참고: 역행렬의 성질(통계수학 II 강의내용 참고)
- \((\mathrm{\mathbf{X}}^{-1})^{-1} = \mathrm{\mathbf{X}}\)
- \((\mathrm{\mathbf{X}}^T)^{-1} = (\mathrm{\mathbf{X}}^{-1})^T\)
- \((\mathrm{\mathbf{XY}})^{-1} = \mathrm{\mathbf{Y}}^{-1}\mathrm{\mathbf{X}}^{-1}\)
행렬식(determinant)
- 행렬의 성질을 대표할 수 있는 하나의 값으로 \(n \times n\) 정방행렬(square matrix)에서 정의
- 역행렬을 구할 때 임의의 행렬이 0, 즉 위 \(2\times 2\) 행렬에서 \(ad - bc\)의 값이 0이라면 역행렬이 존재할 수 없는데 여기서 \(ad - bc\)가 \(2\times 2\) 행렬의 행렬식임
- 임의의 정방행렬 \(\mathrm{\mathbf X}\)의 행렬식은 \(|\mathrm{\mathbf X}|\) 또는 \(\det(\mathrm{\mathbf{X}})\)로 표시함
- \(2\times 2\) 행렬의 행렬식은 넓이, \(3\times 3\) 이상인 정방 행렬에서는 부피의 개념으로 이해할 수 있음
- 정방행렬 \(\mathrm{\mathbf X}_{n\times n}=\{x_{ij}\}\)가 주어졌을 때, \(i\) 번째 행과 \(j\) 번째 열을 제외한 나머지 \((n-1)\times (n-1)\) 정방행렬의 행렬식을 \(|\mathrm{\mathbf{X}}_{ij}|\) 라고 하면 이를 \(x_{ij}\)의 소행렬식(minor)이라 부르고 \(x_{ij}\)의 여인수(co-factor) \(\mathrm{\mathbf{C}}_{ij}\) 는 아래와 같이 정의됨
\[ c_{ij} = (-1)^{i+j}|\mathrm{\mathbf{X}}_{ij}| \]
- 이때 \(\mathrm{\mathbf X}_{n\times n}\) 행렬식은 임의의 \(i\) 또는 \(j\)에 대해 아래의 식을 통해 구할 수 있음
\[ \det(\mathrm{\mathbf{X}}) = \sum_{i=1}^{n}x_{ij}c_{ij} = \sum_{j=1}^n x_{ij}c_{ij} \]
- 행렬식 계산 예시
\[\mathrm{\mathbf{X}} = \begin{bmatrix} 1 &~~~5 &~~~0\\ 2 &~~~4 & -1\\ 0 & -2 &~~~0 \end{bmatrix} \]
\[\begin{aligned} \det(\mathrm{\mathbf{X}}) &= x_{11}\det(\mathrm{\mathbf{X}}_{11}) - x_{12}\det(\mathrm{\mathbf{X}}_{12}) + x_{13}\det(\mathrm{\mathbf{X}}_{13}) \\ & \\ & = 1 \begin{vmatrix} ~~~4 & -1 \\ - 2&~~~0 \end{vmatrix} -5 \begin{vmatrix} 2 & -1 \\ 0 &~~~0 \end{vmatrix} + 0 \begin{vmatrix} 2 &~~~4 \\ 0 & -2 \end{vmatrix} = -2 \end{aligned} \]
- R에서 임의 행렬의 행렬식은
det()
함수를 이용해 구함
<- matrix(c(1, 2, 0, 5, 4, -2, 0, -1, 0), ncol = 3)
X det(X)
[1] -2
참고: 행렬식의 성질(통계수학 II 강의내용 참고)
- 행렬 \(\mathrm{\mathbf{X}}\), \(\mathrm{\mathbf{Y}}\)가 정방행렬이면 \(\det(\mathrm{\mathbf{XY}}) = \det(\mathrm{\mathbf{X}})\det(\mathrm{\mathbf{Y}})\)
- \(\det(\mathrm{\mathbf{X}}) = \det(\mathrm{\mathbf{X}}^T)\)
- \(\det(c\mathrm{\mathbf{X}}) = c^n \det(\mathrm{\mathbf{X}})\) 여기서 \(c\)는 임의의 상수
- \(\det(\mathrm{\mathbf{X}}^{-1}) = \det(\mathrm{\mathbf{X}})^{-1}\)
그외 정칙(non-singluar), 비정칙(non-singular), 양정치(positive definite) 행렬 모두 행렬식으로 정의할 수 있고 자세한 내용은 통계수학 II를 통해 학습. 추가적으로 여인수 \(c_{ij}\) 를 이용한 역행렬 공식은 아래와 같음
\[\mathrm{\mathbf{X}}^{-1} = \frac{1}{\det(\mathrm{\mathbf{X}})} \begin{bmatrix} c_{11} & c_{12} & \cdots & c_{1n} \\ c_{21} & c_{22} & \cdots & c_{2n} \\ \vdots & \vdots & \cdots & \vdots \\ c_{n1} & c_{n2} & \cdots & c_{nn} \end{bmatrix} \]
예습: \(3\times 3\) 정방행렬 \(\mathrm{\mathbf{X}}\)가 아래와 같이 주어졌을 때, \(\mathrm{\mathbf{X}}\)의 행렬식과 역행렬 \(\mathrm{\mathbf{X}}^{-1}\)을 직접 계산해 보고, R에서 각각을 구하는 함수를 사용하여 계산 결과가 맞는지 확인
\[\mathrm{\mathbf{X}} = \begin{bmatrix} 6 & 1 & 4 \\ 2 & 5 & 3 \\ 1 & 1 & 2 \end{bmatrix} \]
2.5.2 행렬의 색인
- R의 행렬 객체 내 데이터 접근은 벡터와 유사하게 행과 열에 대응하는 색인 또는 이름으로 접근 가능
- 행렬의 행과 열은 꺽쇠 `[]’ 안에서 ,(콤마)로 구분
X[idx_row, idx_col]
: 행렬X
의idx_row
행,idx_col
행에 저장된 값 반환(색인번호는 1부터 시작)idx_row
,idx_col
을 지정하지 않으면 전체 행 또는 열을 선택
<- 1:12
x <- matrix(x, ncol = 4)
X X
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
# 1행만 선택
1, ] X[
[1] 1 4 7 10
# 3열만 선택
3] X[,
[1] 7 8 9
# 1:3행만 선택
1:3, ] X[
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
# 1-2행, 3-4열 선택
1:2, 3:4] X[
[,1] [,2]
[1,] 7 10
[2,] 8 11
- 행렬의 각 행과 열에 이름 부여 가능 \(\rightarrow\)
matrix()
함수 인수 중dimnames
에 속성 부여와 동일 dimnames()
함수를 통해 각 행과 열의 이름 확인 및 부여 가능dimnames(object)[[i]], i = 1, 2
를 통해 행(i = 1
)과 열(i = 2
) 이름 변경 및 부여 가능- 위와 유사한 기능을 하는 함수
rownames()
: 헹 이름 반환 및 부여colnames()
: 열 이름 반환 및 부여
# matrix 함수 내에서 행렬 이름 동시 부여
<- matrix(1:9, ncol = 3,
X dimnames = list(c("1", "2", "3"), # 행 이름
c("A", "B", "C")))# 열 이름
X
A B C
1 1 4 7
2 2 5 8
3 3 6 9
# dimnames()를 이용한 이름 확인
dimnames(X) # 행렬에 대한 리스트 반환
[[1]]
[1] "1" "2" "3"
[[2]]
[1] "A" "B" "C"
# dimnames() 함수로 행 이름 변경
dimnames(X)[[1]] <- c("r1", "r2", "r3")
# dimnames() 함수로 열 이름 변경
dimnames(X)[[2]] <- c("c1", "c2", "c3")
dimnames(X)
[[1]]
[1] "r1" "r2" "r3"
[[2]]
[1] "c1" "c2" "c3"
X
c1 c2 c3
r1 1 4 7
r2 2 5 8
r3 3 6 9
# rownames()를 통해 행 이름 확인
rownames(X)
[1] "r1" "r2" "r3"
# colnames()를 통해 열 이름 확인
colnames(X)
[1] "c1" "c2" "c3"
# rownames()를 이용해 행 이름 변경
rownames(X) <- c("apple", "strawberry", "orange")
rownames(X)
[1] "apple" "strawberry" "orange"
# colnames()를 이용해 행 이름 변경
colnames(X) <- c("costco", "emart", "homeplus")
colnames(X)
[1] "costco" "emart" "homeplus"
X
costco emart homeplus
apple 1 4 7
strawberry 2 5 8
orange 3 6 9
- 행과 열에 대한 이름이 존재한다면 벡터와 마찬가지로 이름으로 색인 가능
c("apple", "orange"), c("emart")] X[
apple orange
4 6
# 2번째 열에 해당(emart)를 제외한 나머지 열 반환
colnames(X)[-2]] X[,
costco homeplus
apple 1 7
strawberry 2 8
orange 3 9
- 색인한 행렬 원소에 다른 값 할당
<- c(1:12); Y <- matrix(y, ncol = 3)
y Y
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
# 2, 4 행과 2-3열에 다른 값 할당
c(2, 4), 2:3] <- matrix(c(1, 2, 1, 4), ncol = 2)
Y[
# 행렬 값 할당 다른 예시
<- matrix(nrow = 4, ncol = 3) # NA 값으로 구성된 4 by 3 행렬
X X
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
[3,] NA NA NA
[4,] NA NA NA
<- c(1, 0, 0, 1); Y <- matrix(y, ncol = 2)
y 3:4, 2:3] <- Y
X[ X
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
[3,] NA 1 0
[4,] NA 0 1
- 행렬 필터링 \(\rightarrow\) 색인 대신 조건 사용(벡터와 동일)
= matrix(c(1,2,4,3,2,3,5,6), nrow = 4, ncol = 2)
X
# X의 1열이 3보다 작거나 같은 행 필터링
1] <= 3, ] X[X[,
[,1] [,2]
[1,] 1 2
[2,] 2 3
[3,] 3 6
# 논리값을 활용한 필터링
<- X[, 1] <= 3; idx idx
[1] TRUE TRUE FALSE TRUE
X[idx, ]
[,1] [,2]
[1,] 1 2
[2,] 2 3
[3,] 3 6
2.5.3 행과 열 추가 및 제거
- 행렬 재할당(re-assignment)를 통해 열이나 행을 직접 추가하거나 삭제 가능
cbind()
(열 붙이기, column bind),rbind()
(행 붙이기, row bind) 함수 사용
<- rep(1, 4)
j <- matrix(c(1:4, 1, 1, 0, 0, 1, 0, 1, 0), nrow = 4, ncol = 3)
Z Z
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 1 0
[3,] 3 0 1
[4,] 4 0 0
cbind(j, Z) # 열 기준으로 붙이기
j
[1,] 1 1 1 1
[2,] 1 2 1 0
[3,] 1 3 0 1
[4,] 1 4 0 0
# 길이가 다른 경우 재사용
cbind(1, Z)
[,1] [,2] [,3] [,4]
[1,] 1 1 1 1
[2,] 1 2 1 0
[3,] 1 3 0 1
[4,] 1 4 0 0
# Z 행렬 앞에 j 열 붙혀서 새로운 Z 생성
<- cbind(j, Z)
Z
# 행 기준으로 붙이기
<- rbind(Z, 2) Z
- 행 또는 열의 제거는 벡터에서와 마찬가지로 색인 앞에
-
사용
# 첫 번째 행 제거
-1, ] Z[
j
[1,] 1 2 1 0
[2,] 1 3 0 1
[3,] 1 4 0 0
[4,] 2 2 2 2
# 1, 5행 , 3열 제거
-c(1, 5), -3] Z[
j
[1,] 1 2 0
[2,] 1 3 1
[3,] 1 4 0
cbind()
또는 rbind()
함수는 다음 주에 배울 데이터 프레임에도 적용 가능하다.
2.5.4 행렬 관련 함수
diag()
: 대각행렬 생성 또는 대각원소(diagonal elements) 추출- 대각행렬: 주 대각선을 제외한 모든 원소가 0인 \(n\times n\) 정방행렬로 다음과 같이 정의
\[ \mathrm{\mathbf{D}} = \{d_{ij}\},~~~~i, j \in \{1, 2, \ldots, n\},~~~~\forall~ i \neq j \rightarrow d_{ij} = 0 \]
<- diag(c(1:5), 5)
D D
[,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
# 3차원 항등 행렬(모든 대각원소가 1인 행렬)
<- diag(1, 3)
I3
#대각원소 추출
diag(D)
[1] 1 2 3 4 5
# 대각원소 재할당
diag(D) <- rep(1, 5)
객체는 속성(attribute)을 갖고 그 속성에 따라 데이터의 구조가 정해짐. 즉 속성은 데이터에 대한 메타 데이터임. 객체의 속성은 대표적으로 이름(names), 차원(dimension), 클래스(class)로 정의되고 객제에 대한 자세한 정보를 파악하기 위해 제공되는 몇 가지 함수들에 대해 알아봄.
R은 앞서 언급한 바와 같이 객체지향언어(object oriented program, OOP)이고 세 가지 유형의 객체지향 시스템(S3, S4, S5)이 존재함. R의 핵심적인 함수 및 패키지는 S3 객체 시스템을 사용하고 있기 때문에 알아둘 필요가 있으나 본 강의의 범위를 벗어나기 때문에 이번 학기에는 다루지 않을 것임.
dim(object_name)
: 행렬 또는 데이터 프레임의 행과 열의 개수(차원)를 반환
# dim(): 객체의 차원(dimension)을 반환
Z
j
[1,] 1 1 1 1
[2,] 1 2 1 0
[3,] 1 3 0 1
[4,] 1 4 0 0
[5,] 2 2 2 2
dim(Z)
[1] 5 4
nrow()
또는NROW()
: 행렬의 행 길이 반환ncol()
또는NCOL()
: 행렬의 행 길이 반환
nrow(Z); ncol(Z)
[1] 5
[1] 4
nrow()/ncol()
과NROW()/NCOL()
의 차이점
nrow()/ncol()
은 행렬 또는 데이터 프레임에 적용되며 벡터가 인수로 사용될 때NULL
값을 반환하는데 비해NROW()/NCOL()
은 벡터의 길이도 반환 가능
attributes()
: 객체가 갖는 속성을 반환함
<- 1:9; X <- matrix(x, ncol = 3)
x # 객체의 속성 확인
attributes(x)
NULL
attributes(X)
$dim
[1] 3 3
class()
: 객체의 클래스 명칭 반환 및 클래스 부여
# 객체의 class 확인
class(x); class(X)
[1] "integer"
[1] "matrix" "array"
# 객체의 class 부여
class(x) <- "this is a vector"
str()
: 객체가 갖고 있는 데이터의 구조 확인
# 객체의 구조 파악
str(x); str(X)
'this is a vector' int [1:9] 1 2 3 4 5 6 7 8 9
int [1:3, 1:3] 1 2 3 4 5 6 7 8 9
# x와 X에 이름(name) 속성을 추가한 경우
names(x) <- paste0("x", 1:9)
dimnames(X) <- list(paste0("r", 1:3),
paste0("c", 1:3))
attributes(x); attributes(X)
$class
[1] "this is a vector"
$names
[1] "x1" "x2" "x3" "x4" "x5" "x6" "x7" "x8" "x9"
$dim
[1] 3 3
$dimnames
$dimnames[[1]]
[1] "r1" "r2" "r3"
$dimnames[[2]]
[1] "c1" "c2" "c3"
class(x); class(X)
[1] "this is a vector"
[1] "matrix" "array"
str(x); str(X)
'this is a vector' Named int [1:9] 1 2 3 4 5 6 7 8 9
- attr(*, "names")= chr [1:9] "x1" "x2" "x3" "x4" ...
int [1:3, 1:3] 1 2 3 4 5 6 7 8 9
- attr(*, "dimnames")=List of 2
..$ : chr [1:3] "r1" "r2" "r3"
..$ : chr [1:3] "c1" "c2" "c3"
attr(object, "attribute_name")
: 객체가 갖고 있는 속성을 지정해서 확인
# 객체 속성 요소 확인
attr(x, "names")
[1] "x1" "x2" "x3" "x4" "x5" "x6" "x7" "x8" "x9"
attr(X, "dimnames")
[[1]]
[1] "r1" "r2" "r3"
[[2]]
[1] "c1" "c2" "c3"
2.5.5 벡터와 행렬의 차이점
- 행렬은 개념적으로 \(n \times 1\) 벡터가 2 개 이상 묶어져서 행과 열의 속성을 갖지만 기본적으로는 벡터
<- 1:8
z <- matrix(z, 4, 2)
U length(z) # 입력 벡터 원소의 길이가 8
[1] 8
- R에서
U
가 행렬임을 나타내기 위해 추가적인 속성(attribute)를 부여
class(z) # 벡터
[1] "integer"
attributes(z)
NULL
class(U) # 행렬
[1] "matrix" "array"
attributes(U)
$dim
[1] 4 2
2.5.6 의도치 않은 차원축소 피하기
- 다음 행렬에서 한 행을 추출
<- matrix(c(1:8), 4, 2)
Z <- Z[2, ]
z
attributes(Z) # 행과 열의 차원 수를 표시
$dim
[1] 4 2
# 객체 z의 속성및 형태는?
attributes(z) # 차원이 존재하지 않음
NULL
- 차원축소를 방지하는 방법 \(\rightarrow\)
r
을 벡터가 아닌 \(1 \times 2\) 행렬로 인식
<- Z[2, , drop = FALSE]
z attributes(z)
$dim
[1] 1 2
as.matrix()
를 이용한 직접 변환
<- as.matrix(Z[2, ])
z class(z)
[1] "matrix" "array"
# 행렬이 변환됨을 유의 z
[,1]
[1,] 2
[2,] 6