이번 글에서는 Numpy모듈을 이용하여 행렬의 고윳값을 구한 후 그로 파생된 닮은 행렬을 이용하여 원래 행렬을 다시 구해보는 과정과, 그 과정에서 필자가 저지른 실수에 대해 다뤄보려 한다.
import numpy as np
pycharm 가상환경에서 numpy모듈을 불러온다.
불러온 numpy모듈로 임의의 3*3 행렬 x를 만들어 보자
x = np.array([[1, 2, 3],
[2, 3, 4],
[2, 3, 1]])
numpy에서 세부적인 선형대수적 연산을 위해 제공하는 linalg모듈 (linear algebra: 선형대수) 을
이용하여 간단하게 고윳값과 고유벡터를 구할 수 있다.
xw, xv = np.linalg.eig(x)
이때 xw는 행렬 x의 고윳값, xv 는 행렬 x의 고유벡터를 열로 갖는 배열이다.
print('xw :',xw)
print() #가독성 위한 공백
print('xv :',xv)
-->
xw : [ 7.15502799 -0.21626442 -1.93876357]
xv : [[-0.47946378 -0.82291798 -0.49434482]
[-0.71737964 0.56645335 -0.41737969]
[-0.50545123 -0.04400695 0.76250731]]
이때 대각화 가능한 행렬 A에 대하여
$$A = PDP^{-1}$$ (P 는 A의 고유벡터를 열로갖는 행렬, D는 고윳값을 대각성분으로 갖는 행렬)
가 성립하므로, 행렬 xv의 역행렬을 추가적으로 구해야 한다.
우리의 numpy 는 역행렬을 구하는 아주 편리한 기능 역시 제공하고 있다. inv() 모듈로서 구현 가능하다.
xv_inverse = np.linalg.inv(x)
이렇게 xv의 역행렬 xv_inverse 를 구해내었다.
이때 필자는 성급한 마음에 xv, xw, xv_inverse를 그냥 행렬곱해 버렸는데, 결과는 다음과 같았다.
print(np.matmul(xv,xw,xv_inverse))
-->
[[-2.29419113 -4.44617455 -5.08532195]
[ 2. -1.66666667 0.66666667]
[-0. 0.33333333 -0.33333333]]
기존의 x 행렬과는 전혀 다른 행렬이 도출되었다.
위 식을 다시 보자.
$$A = PDP^{-1}$$
우변의 가운데에 자리하고 있는 행렬 D. 이 행렬의 포맷을 보자.
$$\left[\begin{array}{rrr}
\lambda_{1}&0&0 \\
0&\lambda_{2}&0 \\
0&0&\lambda_{3}
\end{array}\right]$$
대각성분을 각각 A의 고윳값들로 갖는 대각행렬이다.
그러나 필자가 행렬곱의 파라미터로 넘겨준 xw 는
$$\left[\begin{array}{rrr} \lambda_{1} & \lambda_{2} & \lambda_{3} \end{array}\right]$$
이러한 꼴이다. 고로 당연히 원하는 결과를 얻지 못했다.
따라서 오류를 수정하는 과정을 거쳐야 했다. diag() 모듈로 대각행렬을 생성한다.
xw_diag = np.diag([xw[0], xw[1], xw[2]])
-->
[[ 7.15502799 0. 0. ]
[ 0. -0.21626442 0. ]
[ 0. 0. -1.93876357]]
이로서 대각행렬까지 구했다.
다시 행렬곱 연산을 수행한다.
print(np.matmul(xv, xw_diag, xv_inverse))
-->
[[-3.43057674 0.17796788 0.95841773]
[-5.13287138 -0.1225037 0.80920053]
[-3.61651769 0.00951714 -1.47832139]]
오우, 오히려 더 뚱단지 같은 결과값이 도출되었다.
우선 체크해볼 것이 있다.
1. 기존 고윳값과 고유벡터를 도출하는 과정에 있어서 오류 유무
2. 행렬 X 의 대각화 가능 여부
3. 코드상의 문제가 아닌 프로그램 연산 상의 오류 유무
위 3가지 것들을 우선적으로 확인하고, 재검토가 필요하다.
'Python > Numpy' 카테고리의 다른 글
Python Numpy - 넘파이 기본과 예제 (0) | 2020.01.25 |
---|
댓글