TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 - 수학 | 통계학>

[개발자를 위한 수학] 선형대수학: 행렬

by 기록자_Recordian 2024. 10. 7.
728x90
반응형
이전 내용

 

 

[개발자를 위한 수학] 선형대수학: 벡터, 선형변환

선형대수학 선형대수학(linear algebra): 벡터 공간, 벡터, 선형 변환, 행렬, 연립 선형 방정식 등을 연구하는 대수학의 한 분야이다. 현대 선형대수학은 그중에서도 벡터 공간이 주 

puppy-foot-it.tistory.com


행렬(matrix)

 

행렬은 여러 개의 행과 열을 가질 수 있으며 데이터를 묶는 편리한 방법이다. 행렬은 2차원 이상의 숫자 격자로 표현된 벡터의 집합이다.

 

◆ 행렬 벡터 곱셈(matrix vector multiplication)

기저벡터: 모든 벡터를 만들거나 변환하기 위한 구성 요소.

 

행렬에 담긴 기저 벡터 i(i햇)과 (j햇)이 있을 때 벡터 v를 변환하는 공식은 다음과 같다.

i은 첫 번째 열 [a, c] 이고 j은 두 번째 열 [b, d] 이다. 이 두 기저 벡터를 하나의 행렬에 넣었다. 

기저 벡터를 적용해 다른 벡터를 위와 같이 변환하는 것을 행렬 벡터 곱셈이라고 부른다.

 

파이썬에서 넘파이를 사용해 이 변환을 수행하려면 기저 벡터를 행렬로 선언한 다음 dot() 연산을 사용해 벡터 v에 적용한다. (dot() 연산은 행렬과 벡터 사이의 스케일링과 덧셈을 수행하며, 이를 점 곱 이라고 한다.)

 

[넘파이의 행렬 벡터 곱셈]

# 넘파이의 행렬 벡터 곱셈
from numpy import array

# i-hat과 j-hat으로 구성된 기저 행렬 생성
basis = array(
    [[3, 0],
     [0, 2]]
)

# 벡터 v 정의
v = array([1, 1])

# 점 곱으로 v에 변환을 적용해 새로운 벡터 생성
new_v = basis.dot(v)

print(new_v)

 

기저 벡터를 각각 만든 다음 하나의 행렬로 구성할 때 넘파이의 array() 함수는 각 벡터를 열이 아닌 행으로 채우기 때문에 행과 열을 바꿔야 하는데, 이를 전치라고 한다.

 

★ 전치 행렬: 선형대수학에서 전치 행렬(transposed matrix)은 행과 열을 교환하여 얻는 행렬이다. 즉, 주대각선을 축으로 하는 반사 대칭을 가하여 얻는 행렬이다.

출처: 위키백과

 

[기저 벡터를 분리해 변환 수행하기 - 전치 연산의 예시]

# 전치 연산 예시
from numpy import array

# i-hat 과 j-hat 선언
i_hat = array([2, 0])
j_hat = array([0, 3])

# i-hat과 j-hat을 사용해 기저 행렬 생성 (열과 행 바꿔야 함)
basis = array([i_hat, j_hat]).transpose()

# 벡터 v 선언
v = array([1,1])

# 점 곱으로 v에 변환을 적용해 새로운 벡터 생성
new_v = basis.dot(v)

print(new_v)

 

Q1. 벡터 v는 [2, 1] 이고, i과 j 각각 [1,0] 및 [0,1]이다. 그다음 i과 j을 [2,0]과 [0,3]으로 변환할 경우, 벡터 v는 어떻게 되는가?

위의 공식을 파이썬의 넘파이를 사용하면

# 벡터 변환하기
from numpy import array

# i-hat 과 j-hat 선언
i_hat = array([2, 0])
j_hat = array([0, 3])

# i-hat과 j-hat을 사용해 기저 행렬 생성 (열과 행 바꿔야 함)
basis = array([i_hat, j_hat]).transpose()

# 벡터 v 선언
v = array([2,1])

# 점 곱으로 v에 변환을 적용해 새로운 벡터 생성
new_v = basis.dot(v)

print(new_v)

 

Q2. 벡터 v는 [2, 1] 이고, i과 j 각각 [1,0] 및 [0,1]이다. 그다음 i과 j을 [2,3]과 [2,-1]으로 변환할 경우, 벡터 v는 어떻게 되는가?

# 벡터 변환하기2
from numpy import array

# i-hat 과 j-hat 선언
i_hat = array([2, 3])
j_hat = array([2, -1])

# i-hat과 j-hat을 사용해 기저 행렬 생성 (열과 행 바꿔야 함)
basis = array([i_hat, j_hat]).transpose()

# 벡터 v 선언
v = array([2,1])

# 점 곱으로 v에 변환을 적용해 새로운 벡터 생성
new_v = basis.dot(v)

print(new_v)


행렬 곱셈

 

행렬 곱셈은 벡터 공간에 여러 개의 변환을 적용하는 것이며, 각 변환은 하나의 함수와 같다.

가장 안쪽을 먼저 적용한 다음, 바깥쪽 방향으로 계속 변환을 적용한다.

 

[x,y] 값을 가진 벡터 v에 회전과 전단을 적용하는 방법

 

  • 첫 번째 변환을 두 번째 변환에 적용함으로써 두 변환을 통합
  • 첫 번째 행렬의 각 행을 두 번째 행렬의 각 열에 '위-아래, 위-아래' 패턴으로 곱하고 더한다

파이썬에서 넘파이를 사용해 이 작업을 실행하려면 matmul() 또는 @ 연산자를 사용해 두 행렬을 곱하면 된다.

# 두 변환 결합
from numpy import array

# 변환1
i_hat1 = array([0, 1])
j_hat1 = array([-1, 0])
transform1 = array([i_hat1, j_hat1]).transpose()

# 변환2
i_hat2 = array([1, 0])
j_hat2 = array([1, 1])
transform2 = array([i_hat2, j_hat2]).transpose()

# 변환 통합
combined = transform2 @ transform1

# 테스트
print("결합된 행렬:\n {}".format(combined))

v = array([1, 2])
print(combined.dot(v))

★ 행렬 곱셈의 경우, 교환 법칙이 성립하지 않으므로 transform의 순서를 바꾸면(transform1을 transform2에 적용) 같은 결과를 기대할 수 없다. 

# 변환 반대로 적용
combined2 = transform1 @ transform2

# 테스트
print("통합 행렬:\n {}".format(combined2))
print(combined2.dot(v))


행렬식(determinant)

 

행렬식은 두 벡터로 형성된 영역이 선형 변환에 따라 크기가 얼마나 변화하는지 설명한다. 이는 변환에 대한 유용한 정보이다.

 

[파이썬으로 행렬식 계산하기]

# 파이썬으로 행렬식 계산하기
from numpy.linalg import det
from numpy import array

i_hat = array([3, 0])
j_hat = array([0, 2])

basis = array([i_hat, j_hat]).transpose()

determinant = det(basis)

print(determinant)

 

단순한 전단이나 회전은 면적이 변하지 않으므로 행렬식에 영향을 주지 않아야 한다.

★ Numpy의 `numpy.linalg.det` 함수는 주어진 정사각 행렬의 determinant(행렬식)을 계산하는 함수이다. 행렬식은 선형 변환의 스케일링 요인을 나타내며, 행렬이 역행렬을 가지는지 여부를 결정하는 데 중요한 역할을 한다. 이 함수는 주어진 행렬의 determinant를 계산하여 반환한다.

 

하지만 스케일링은 샘플링된 영역을 늘리거나 줄이므로 행렬식을 늘리거나 줄일 수 있다. 방향이 뒤집히면(i과 j을 시계 방향으로 위치를 교환하면) 행렬식은 음수가 된다.

 

[음수 행렬식]

# 음수 행렬식
from numpy.linalg import det
from numpy import array

i_hat = array([-2, 1])
j_hat = array([1, 2])

basis = array([i_hat, j_hat]).transpose()

determinant = det(basis)

print(determinant)

이 행렬식은 음수이므로 방향이 뒤집힌 것을 금방 알 수 있다. 그러나 행렬식이 알려주는 가장 중요한 정보는 변환이 선형 종속인지의 여부인데, 행렬식이 0이면 모든 공간이 더 작은 차원으로 줄어들었다는 뜻이다.

 

예를 들어, 2차원 공간이 1차원으로 압축되거나 3차원 공간이 2차원으로 압축되는 등의 선형 종속 변환의 경우, 면적과 부피는 모두 0이다.

 

[2차원 공간을 하나의 1차원 직선으로 줄인 후, 행렬식 계산]

# 2차원 공간을 하나의 1차원 직선으로 줄인 후, 행렬식 계산
from numpy.linalg import det
from numpy import array

i_hat = array([3, -1.5])
j_hat = array([-2, 1])

basis = array([i_hat, j_hat]).transpose()

determinant = det(basis)

print(determinant)

 

0 행렬식을 테스트 하는 것은 변환에 선형 종속이 있는지 확인하는 데 매우 유용하며, 이 문제가 발생하면 해결하기 어렵거나 해결할 수 없는 문제일 가능성이 높다.


특수 행렬

 

◆ 정방 행렬(square matrix)

행과 열의 수가 같은 행렬. 주로 선형 변환을 표현하는 데 사용되며 고윳값 분해와 같은 많은 연산에 필수적인 행렬이다.

 

◆ 항등 행렬(identity matrix)

대각선의 값이 1이고 다른 값은 0인 정방 행렬. 단위 행렬이라고도 한다.

항등 행렬을 만들 수 있다면 변환을 취소하고 우너래 기저 벡터를 찾았다는 뜻이다.

◆ 역 행렬(inverse matrix)

다른 행렬의 변환을 취소하는 행렬이다.

역행렬과 행렬을 행렬 곱셈하면 항등 행렬이 된다.

 

◆ 대각 행렬(diagonal matrix)

대각선에는 0이 아닌 값이 있고 나머지 값은 0인 행렬.

벡터 공간에 적용되는 간단한 스칼라 값을 나타내기 때문에 특정 계산에 필요하다.

◆ 삼각 행렬(triangular matrix)

대각선과 대각선 위쪽 또는 아래쪽 원소에는 값이 있고 나머지 원소는 0인 행렬.

일반적으로 연립 방정식으로 풀기 쉽기 때문에 많은 수치 분석 작업에서 선호된다.

 

◆ 희소 행렬(sparse matrix)

0이 대부분이고 0이 아닌 원소가 매우 적은 행렬.컴퓨팅 관점에서 보면 행렬의 원소가 대부분 0인 경우 희소 행렬을 만들면 0을 저장하는 데 공간을 낭비하지 않고 0이 아닌 원소만 기록할 수 있기 때문에 효율성을 높일 수 있다.


다음 내용

 

[개발자를 위한 수학] 선형대수학: 연립 방정식과 역행렬

이전 내용 [개발자를 위한 수학] 선형대수학: 행렬이전 내용  [개발자를 위한 수학] 선형대수학: 벡터, 선형변환선형대수학 선형대수학(linear algebra): 벡터 공간, 벡터, 선형 변환, 행렬, 연

puppy-foot-it.tistory.com


[출처]

개발자를 위한 필수 수학

업무자동화 - 티스토리

위키백과

728x90
반응형