개발일기

기초 수학 - 행렬 본문

Deep Learning, Machine Learning/기초 수학

기초 수학 - 행렬

Flashback 2024. 3. 27. 22:06
728x90
반응형

 

대칭행렬

전치 행렬이 기존 행렬과 동일하면 대칭행렬이라 한다. 즉 행렬의 전치는 자기 자신이 된다. 수식으로는 $ X = X^T $ 로 표시한다.

# Symmetric Matrix
import numpy as np

X = np.array([[0, 5, 6],
             [5, 1, 9],
             [6, 9, 3]])

print("X: \\n", X, "\\n")
print("X Transpose: \\n", X.T)

"""
X: 
 [[0 5 6]
 [5 1 9]
 [6 9 3]] 

X Transpose: 
 [[0 5 6]
 [5 1 9]
 [6 9 3]]
"""

단위 행렬

행렬 대각선의 주축 요소들은 1이고 이를 제외한 나머지 요소가 0인 행렬을 단위행렬이라 한다. 단위행렬은 수식에서 $I  $로 표시하며 $ I_3 = \begin{pmatrix}1 & 0 & 0 \\0 & 1 & 0 \\0 & 0 & 1 \\\end{pmatrix} $ 행렬 크기에 따라 $ I $의 아래첨자 수가 달라진다. 만약 (2, 2) 크기의 단위 행렬을 만드면 $ I_2 $로 표시한다.

# Identity Matrix
import numpy as np

X = np.array([[1, 0, 0, 0, 0],
              [0, 1, 0, 0, 0],
              [0, 0, 1, 0, 0],
              [0, 0, 0, 1, 0],
              [0, 0, 0, 0, 1]])

print("X: \\n", X)

"""
X: 
 [[1 0 0 0 0]
 [0 1 0 0 0]
 [0 0 1 0 0]
 [0 0 0 1 0]
 [0 0 0 0 1]]
"""

단위행렬의 이러한 특징으로 인해 행렬 A에 A와 동일한 크기의 단위 행렬을 곱하면 A 행렬 자신이 반환되는 특징을 가지고 있다.

# Identity Matrix 1
import numpy as np

I = np.array([[1, 0, 0],
              [0, 1, 0],
              [0, 0, 1]])
A = np.array([[1, 1, 9],
              [3, 5, 8],
              [1, 2, 5]])

print("A * I: \\n", np.dot(A, I))

"""
A * I: 
 [[1 1 9]
 [3 5 8]
 [1 2 5]]
"""

두 행렬을 곱한 결과 A의 행렬이 출력된다.

 

Pytorch 단위 행렬

# Identity Matrix Pytorch
import torch

I = torch.tensor([[1, 0, 0],
                  [0, 1, 0],
                  [0, 0, 1]])

A = torch.tensor([[1, 1, 9],
                  [3, 5, 8],
                  [1, 2, 5]])

print("A * I: \\n", torch.matmul(A, I))

"""
A * I: 
 tensor([[1, 1, 9],
        [3, 5, 8],
        [1, 2, 5]])
"""

 

Tensorflow 단위 행렬

# Identity Matrix Tensorflow
import tensorflow as tf

I = tf.Variable([[1, 0, 0],
                 [0, 1, 0],
                 [0, 0, 1]])

A = tf.Variable([[1, 1, 9],
                 [3, 5, 8],
                 [1, 2, 5]])

print("A * I: \\n", tf.matmul(A, I))

"""
A * I: 
 tf.Tensor(
[[1 1 9]
 [3 5 8]
 [1 2 5]], shape=(3, 3), dtype=int32)
"""

matmul(): 두 행렬을 곱하는 메서드이다. pytorch와 tensorflow에서 사용된다.

대각 행렬

주 대각선 성분을 제외한 모든 성분이 0인 행렬을 의미한다. 위에서 언급한 단위 행렬은 대각 행렬중 하나이다. 단위 행렬과의 차이는 단위 행렬은 주 대각선 요소가 모두 1이지만 대각 행렬은 3, 5, 8 등 다양한 숫자가 위치해도 된다는 특징을 가지고 있다.

# Diagonal Matrix
import numpy as np

diag = np.array([[3, 0, 0],
                 [0, 5, 0],
                 [0, 0, 8]])

print("Diagonal Matrix: \\n", diag)

"""
Diagonal Matrix: 
 [[3 0 0]
 [0 5 0]
 [0 0 8]]
"""

 

역행렬

역행렬은 숫자의 역수와 비슷한 개념이다. 숫자 3의 분모와 분자를 뒤집으면 1/3이 되고 그 둘을 곱하면 1이라는 값이 나온다. 역행렬도 이와 비슷한 개념으로 행렬에 역행렬을 곱하면 단위 행렬이 나오는 행렬이다. 수학 수식으로는 행렬 위첨자로 -1을 추가하여 $ A \cdot A^{-1} = I $로 표시한다.

역행렬은 2x2, 3x3…와 같이 정방 행렬인 경우에 존재한다. 역행렬이 존재하는 행렬에 다른 행렬을 곱하면 곱하는 순서에 따라 다른 값이 나온다. 하지만 역행렬은 곱하는 순서에 상관없이 단위 행렬이 나오는 특징이 있다. $ A\cdot B \neq  B \cdot A $   ,  $ A\cdot A^{-1} = A^{-1}\cdot A $

하지만 모든 정방 행렬에서 역행렬이 존재하는건 아니다. $  \begin{pmatrix}a & b \\c & d \\\end{pmatrix} $ 이런 행렬이 있을때, $ ad - bc \neq 0 $면 역행렬이 존재한다는 의미이며 이와 반대로 $ ad - bc = 0 $이면 역행렬이 없다는 의미이다.

$ \begin{pmatrix}3 & -2 \\-3 & 2 \\\end{pmatrix} \begin{pmatrix} 2 & 5 \\ 1 & 6 \\ \end{pmatrix} $  이 두 행렬 중 왼쪽 행렬은 3x2 - (-2 x -3) = 0이므로 역행렬이 존재하지 않고 오른쪽 행렬은 2x6 - (1x5) = 7로 역행렬이 존재한다. 이러한 역행렬은 주로 선형 방정식을 풀 때 미지수의 값을 찾아내는 용도로 사용된다.

$ \begin{pmatrix}2 & -3 \\-1 & 5 \\\end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} = \begin{pmatrix} 10 \\ 20 \end{pmatrix} $

행렬에 역행렬을 구하면 단위 행렬이 된다는 식을 기억하면 미지수를 쉽게 찾아낼 수 있다.

$ \begin{pmatrix}2 & -1 \\-5 & 3 \\\end{pmatrix} \begin{pmatrix} 2 & -1 \\ -5 & 3 \\ \end{pmatrix}^{-1} \begin{pmatrix} x \\ y \end{pmatrix} = \begin{pmatrix} 2 & -1 \\ -5 & 3 \\ \end{pmatrix}^{-1} \begin{pmatrix} 10 \\ 20 \end{pmatrix} $

단위 행렬이 되면 좌변은 $ \begin{pmatrix} x \\ y \end{pmatrix} $만 남게 되고 우변은 역행렬과 $ \begin{pmatrix} 10 \\ 20 \end{pmatrix} $이 남게 된다. 이제 미지수 $ x, y $ 를 구하려면 역행렬과 $ (10, 20)^T $의 행렬곱만 구하면 값을 쉽게 찾을 수 있다.

 

numpy 역행렬

numpy에서 역행렬을 구할 때 사용하는 np.linalg.inv()메서드를 활용하여 미지수값을 구할 수 있다.

# Matrix Inversion
import numpy as np

A = np.array([[2, -5],
              [-1, 3]]) # A행렬
B = np.array([10, 20]) # B행렬

print("A역행렬: \\n", np.linalg.inv(A)) # 역행렬 출력
print("\\n")
print("A x A역행렬: \\n", np.dot(A, np.linalg.inv(A))) # A행렬 x A역행렬
print("\\n")
print("미지수 x, y: \\n", np.dot(np.linalg.inv(A), B)) # 미지수 x, y

"""
A역행렬: 
 [[3. 5.]
 [1. 2.]]

A x A역행렬: 
 [[1. 0.]
 [0. 1.]]

미지수 x, y: 
 [130.  50.]
"""
# 역행렬 미지수 검증
import numpy as np

X = np.array([130, 50])
A = np.array([[2, -5], [-1, 3]])

print(np.dot(A, X)) # array([10, 20])

미지수가 올바른지 검증하려면 A행렬에 $ \begin{pmatrix} 130 \\ 50 \end{pmatrix} $ 를 곱하여 $ \begin{pmatrix} 10 \\ 20 \end{pmatrix} $이 정상적으로 나오는걸로 검증을 진행할 수 있다.

$ \begin{pmatrix}
2 & -5 \\
-1 & 3 \\
\end{pmatrix} \begin{pmatrix}
130 \\ 50
\end{pmatrix} = \begin{pmatrix}
10 \\ 20
\end{pmatrix} $

 

이러한 역행렬을 계산할 때 행렬이 선형 독립이 서로 평행하거나 완전히 일치하는 특수한 행렬의 상태일경우 역행렬 계산이 불가능하다.

직교 행렬

행렬의 전치가 행렬의 역행렬과 동일하며 행렬과 전치 행렬을 곱하면 단위 행렬이 반환된다. 수식으로 보면 $  A^TA = AA^T = I $ , $ A^T = A^{-1} $ 로 표현한다. 또한 이름이 직교 행렬인 이유는 행렬의 행 벡터와 열 벡터 간의 사이 각도가 90도를 이루고 있으며 두 벡터의 내적값이 0이므로 직교 행렬이라 부른다.

 


https://colab.research.google.com/drive/18_f58EVVC6SMDYM1cmpVC_2qHukx_9ob?usp=sharing

 

행렬.ipynb

Colaboratory notebook

colab.research.google.com

 

728x90
반응형
Comments