[선형대수학] 벡터와 행렬의 연산 - 전치, 열벡터선형조합, 부분행렬

전치연산, 열벡터선형조합, 부분행렬 등 벡터와 행렬의 기본 연산 관련 내용을 정리합니다.

벡터-행렬의 덧셈과 뺄셈

element-wise 요소 별 연산
$x+y=\left[\begin{array}{l}
10 \\
11 \\
12
\end{array}\right]+\left[\begin{array}{l}
0 \\
1 \\
2
\end{array}\right]=\left[\begin{array}{l}
10+0 \\
11+1 \\
12+2
\end{array}\right]=\left[\begin{array}{l}
10 \\
12 \\
14
\end{array}\right]
$

스칼라와 벡터/행렬의 곱셈

벡터, 행렬의 모든 원소에 스칼라 c를 곱한다.
$c \begin{bmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{bmatrix} = \begin{bmatrix} ca_{11} & ca_{12} \\ ca_{21} & ca_{22} \end{bmatrix}$

  • 벡터/행렬에 스칼라값을 곱한 후 더하거나 뺀 것은 Linear combination 선형조합을 한 것과 같다.
    $c_1x_1 + c_2x_2 + c_3x_3 + \cdots + c_Lx_L = x$

행렬-벡터 곱셈

머신러닝에서 가장 많이 활용되는 행렬-벡터의 곱 $M v$은 각각의 크기를 사각형으로 표시한다면 다음과 같다.

열 벡터의 선형조합

Matrix-Vector Products 행렬-벡터 곱셈은 열벡터의 linear combination 선형조합을 한 결과 벡터와 같다.

$\begin{split}
\begin{align}
Xw=
\begin{bmatrix}
c_1 & c_2 & \cdots & c_m
\end{bmatrix}
\begin{bmatrix}
w_1 \\ w_2 \\ \vdots \\ w_m
\end{bmatrix}
=
w_1 c_1 + w_2 c_2 + \cdots + w_m c_m
\end{align}
\end{split}
$

  • 행렬 $X$와 벡터 $w$의 곱은 ⅰ,ⅱ 를 각각 곱한 것의 합이라고 할 수 있다.

    1. 행렬 $X$를 이루는 열벡터 : $\begin{bmatrix} c_1 & c_2 & \cdots & c_m\end{bmatrix}$
    2. 뒤의 벡터 $w$ 요소 : $w_{1}, w_{2}, \ldots, w_{m}$
  • 행렬을 이루는 열벡터로 변환하는 것 $\mathbf{X} \in \mathbb{R}^{n \times m}$이라고 가정할 때, 행렬을 transformation that projects vectors from $\mathbb{R}^{n} \text { to } \mathbb{R}^{m}$

  • 행렬을 이루는 열벡터와 뒤의 벡터간의 연산으로 선형조합을 나타내면 다음과 같다.

tf.linalg.matvec

A.shape, x.shape, tf.linalg.matvec(A, x)
(TensorShape([5, 4]),
 TensorShape([4]),
 <tf.Tensor: shape=(5,), dtype=float32, numpy=array([ 14.,  38.,  62.,  86., 110.], dtype=float32)>)

↪ 행렬 $\mathbf{A} \in \mathbb{R}^{5 \times 4}$ 과 벡터$\mathbf{x} \in \mathbb{R}^{4}$의 연산의 결과 $\mathbf{A}\mathbf{x}$는 길이 $m=5$의 벡터이다.

브로드캐스팅

$\begin{bmatrix} 10 \\ 11 \\ 12 \\ \end{bmatrix} - 10 = \begin{bmatrix} 10 \\ 11 \\ 12 \\ \end{bmatrix} - 10\cdot \mathbf{1} = \begin{bmatrix} 10 \\ 11 \\ 12 \\ \end{bmatrix} - \begin{bmatrix} 10 \\ 10 \\ 10 \\ \end{bmatrix}$

Array Broadcasting in Numpy

Broadcasting — NumPy v1.21 Manual

a = np.array([1.0, 2.0, 3.0])
b = np.array([2.0, 2.0, 2.0])
a * b
array([ 2.,  4.,  6.])

a = np.array([1.0, 2.0, 3.0])
b = 2.0
a * b
array([ 2.,  4.,  6.])

전치 연산

Transposition : interchange rows with columns.
전치 연산은 행렬의 행과 열을 바꾸는 연산이다. 행렬 $A$의 전치행렬은 $A', A^T$로 표기한다.

행렬 $\mathbf{A} ∈ R^{m×n}$이고 $\mathbf{B} = \mathbf{A}^T$이면, 행렬 $\mathbf{B} ∈ R^{n×m}$ with $\mathbf{b_{ij}} =\mathbf{a_{ij}}$이다.

$X = \begin{bmatrix} \boxed{\begin{matrix} x_{1, 1} & x_{1, 2} & x_{1, 3} & x_{1, 4}\end{matrix}} \\ \begin{matrix} x_{2, 1} & x_{2, 2} & x_{2, 3} & x_{2, 4}\end{matrix} \\ \begin{matrix} x_{3, 1} & x_{3, 2} & x_{3, 3} & x_{3, 4}\end{matrix} \\ \begin{matrix} x_{4, 1} & x_{4, 2} & x_{4, 3} & x_{4, 4}\end{matrix} \\ \begin{matrix} x_{5, 1} & x_{5, 2} & x_{5, 3} & x_{5, 4}\end{matrix} \\ \begin{matrix} x_{6, 1} & x_{6, 2} & x_{6, 3} & x_{6, 4}\end{matrix} \\ \end{bmatrix} \rightarrow X^T = \begin{bmatrix} \boxed{\begin{matrix} x_{1, 1} \\ x_{1, 2} \\ x_{1, 3} \\ x_{1, 4}\end{matrix}} & \begin{matrix} x_{2, 1} \\ x_{2, 2} \\ x_{2, 3} \\ x_{2, 4}\end{matrix} & \begin{matrix} x_{3, 1} \\ x_{3, 2} \\ x_{3, 3} \\ x_{3, 4}\end{matrix} & \begin{matrix} x_{4, 1} \\ x_{4, 2} \\ x_{4, 3} \\ x_{4, 4}\end{matrix} & \begin{matrix} x_{5, 1} \\ x_{5, 2} \\ x_{5, 3} \\ x_{5, 4}\end{matrix} & \begin{matrix} x_{6, 1} \\ x_{6, 2} \\ x_{6, 3} \\ x_{6, 4}\end{matrix} & \end{bmatrix}$

전치연산관련 행렬의 성질

  • $(\mathbf{A B})^{\top}=\mathbf{B}^{\top} \mathbf{A}^{\top}$
  • $(\mathbf{A}^{T})^{T}= \mathbf{A}$
  • $(\mathbf{A+B})^{T}=\mathbf{A}^{T}+\mathbf{B}^{T}$
  • 행렬$\mathbf{A}$가 Symmetric 대칭행렬이면 ⇒ $\mathbf{A}=\mathbf{A}^{\top}$
  • 행렬 $\mathbf{A}$가 orthogonal 직교행렬이면 ⇒ $\mathbf{A} \mathbf{A}^{\top}=\mathbf{A}^{\top} \mathbf{A}=\mathbf{I} \text { or } \mathbf{A}^{-1}=\mathbf{A}^{\top}$

tf.transpose

## (1) 원래의 행렬이 대칭행렬이 아닌경우  
A = tf.reshape(tf.range(20), (5, 4))
A 
<tf.Tensor: shape=(5, 4), dtype=int32, numpy=
array([[ 0,  1,  2,  3],
     [ 4,  5,  6,  7],
     [ 8,  9, 10, 11],
     [12, 13, 14, 15],
     [16, 17, 18, 19]], dtype=int32)>
tf.transpose(A)  
<tf.Tensor: shape=(4, 5), dtype=int32, numpy=  
array([[ 0, 4, 8, 12, 16],  
[ 1, 5, 9, 13, 17],  
[ 2, 6, 10, 14, 18],  
[ 3, 7, 11, 15, 19]], dtype=int32)>

## (2)원래의 행렬이 대칭행렬인 경우, 전치연산의 결과가 원래의 행렬과 같다. 
B = tf.constant([[1, 2, 3], [2, 0, 4], [3, 4, 5]])
B
<tf.Tensor: shape=(3, 3), dtype=int32, numpy=
array([[1, 2, 3],
       [2, 0, 4],
       [3, 4, 5]], dtype=int32)>
B == tf.transpose(B)
<tf.Tensor: shape=(3, 3), dtype=bool, numpy=
array([[ True,  True,  True],
       [ True,  True,  True],
       [ True,  True,  True]])>

부분행렬

submatrix 부분행렬을 활용해 두 행렬의 곱을 여러가지 방법으로 계산할 수도 있다.

$2 \times 2$ 정방행렬 $A,B$의 곱을 예로 살펴보자.

$A=\left[\begin{array}{ll}
a_{11} & a_{12} \\
a_{21} & a_{22}
\end{array}\right], \quad B=\left[\begin{array}{ll}
b_{11} & b_{12} \\
b_{21} & b_{22}
\end{array}\right]$

1. 앞의 행렬을 행벡터로 나누어 계산한다.

$a_{1}^{T}=\left[\begin{array}{ll}a_{11} & a_{12}\end{array}\right], \quad a_{2}^{T}=\left[\begin{array}{ll}a_{21} & a_{22}\end{array}\right]$

2. 뒤의 행렬을 열벡터로 나누어 계산한다.

$b_{1}=\left[\begin{array}{l}b_{11} \\b_{21}\end{array}\right], \quad b_{2}=\left[\begin{array}{l}b_{21} \\b_{22}\end{array}\right]$

3. 앞의 행렬을 열벡터로, 뒤의 행렬을 행벡터로 나누어 스칼라처럼 계산한다.

$AB=\left[\begin{array}{ll}a_{1} & a_{2}\end{array}\right]\left[\begin{array}{l}b_{1}^{T} \\b_{2}^{T}\end{array}\right]=a_{1} b_{1}^{T}+a_{2} b_{2}^{T}$


Source&Reference: 김도형의 데이터사이언스 스쿨