Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python에서 SVD(특이값 분해)로 행렬의 순위 구하기: rank-deficient 행렬 처리 방법

Python에서 배열의 행렬 순위(matrix rank)를 구하려면 numpy.linalg.matrix_rank() 메서드를 사용하면 됩니다. 이 메서드는 내부적으로 SVD(특이값 분해, Singular Value Decomposition) 기법을 활용하여 순위를 계산합니다.

배열의 순위란 tol(허용 오차)보다 큰 특이값(singular value)의 개수를 의미합니다. 예를 들어 5×5 단위행렬은 모든 특이값이 1이므로 순위가 5지만, 대각 원소 하나를 0으로 만들면 순위가 4로 떨어지는 rank-deficient(순위 부족) 행렬이 됩니다.

numpy.linalg.matrix_rank() 주요 매개변수

1. A

순위를 계산할 입력 배열입니다. 단일 벡터, 행렬 또는 여러 행렬이 쌓인(stack of matrices) 형태의 배열도 전달할 수 있습니다.

2. tol

SVD 값이 0으로 간주되는 임계값(threshold)입니다. tol=None(기본값)으로 두고, S가 특이값 배열, M과 N이 행렬의 크기, eps가 해당 데이터 타입의 엡실론 값이라면 tol은 다음과 같이 자동 설정됩니다.

tol = S.max() * max(M, N) * eps

즉, 최대 특이값에 행렬 차원과 머신 엡실론을 곱한 값이 기준이 되어 수치적 노이즈를 무시하고 실질적인 순위를 판별합니다.

3. hermitian

True로 지정하면 입력 행렬 A가 에르미트(Hermitian) 행렬이라고 가정합니다. 이 경우 고유값 분해를 활용하는 더 효율적인 알고리즘으로 특이값을 계산할 수 있어 성능상 이점이 있습니다. 기본값은 False입니다.

구현 단계

1단계: 필요한 라이브러리 임포트

import numpy as np
from numpy.linalg import matrix_rank

2단계: 배열 생성 및 확인

np.eye(5)로 5×5 단위행렬(identity matrix)을 생성합니다.

arr = np.eye(5)

# 배열 출력
print("Our Array...\n", arr)

# 차원 확인
print("\nDimensions of our Array...\n", arr.ndim)

# 데이터 타입 확인
print("\nDatatype of our Array object...\n", arr.dtype)

# 형태(shape) 확인
print("\nShape of our Array object...\n", arr.shape)

3단계: 행렬 순위 계산 및 rank-deficient 행렬 테스트

matrix_rank()로 원래 행렬의 순위를 구한 뒤, 마지막 대각 원소를 0으로 변경하여 순위가 감소하는지 확인합니다.

print("\nRank...\n", matrix_rank(arr))

arr[-1, -1] = 0.
print("\nUpdated Rank (Rank-Deficit Matrix)...\n", matrix_rank(arr))

전체 예제 코드

import numpy as np
from numpy.linalg import matrix_rank

# 배열 생성
arr = np.eye(5)

# 배열 출력
print("Our Array...\n", arr)

# 차원 확인
print("\nDimensions of our Array...\n", arr.ndim)

# 데이터 타입 확인
print("\nDatatype of our Array object...\n", arr.dtype)

# 형태(shape) 확인
print("\nShape of our Array object...\n", arr.shape)

# numpy.linalg.matrix_rank()로 행렬 순위 반환
print("\nRank...\n", matrix_rank(arr))

arr[-1, -1] = 0.
print("\nUpdated Rank (Rank-Deficit Matrix)...\n", matrix_rank(arr))

실행 결과

Our 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.]]

Dimensions of our Array...
2

Datatype of our Array object...
float64

Shape of our Array object...
(5, 5)

Rank...
5

Updated Rank (Rank-Deficit Matrix)...
4

결과 해석

처음 생성한 5×5 단위행렬은 서로 독립인 5개의 행(또는 열)을 가지므로 순위가 5로 출력됩니다. 그러나 마지막 대각 원소를 0으로 바꾸면 하나의 행이 영벡터가 되어 선형 종속이 발생하고, 순위는 4로 감소합니다. 이렇게 순위가 전체 차원보다 작아진 행렬을 rank-deficient(순위 부족) 행렬이라고 부릅니다.

matrix_rank()는 SVD 기반으로 동작하기 때문에 부동소수점 연산 오차가 있는 경우에도 tol 매개변수를 통해 수치적 안정성을 확보하면서 정확한 순위를 판별할 수 있습니다.