gyeo-ri.com

고윳값과 고유벡터 본문

카테고리 없음

고윳값과 고유벡터

겨리_Gyeori 2021. 1. 17. 13:31

고윳값(Eigen Value)과 고유벡터(Eigen Vector)

 


  고윳값과 고유벡터는 데카르트 좌표계(xy 좌표평면 등 일반적으로 사용되는 좌표 표현 방식)의 벡터를  방향이 변하지 않는 새로운 축에서의 선형 변환을 표현하는 형태로 자주 설명된다. 이 때 새로운 축 위의 점을 고유벡터라고 하고, 고윳값이 선형변환에 의해 벡터가 얼마나 이동하느냐를 나타낸다. 엄밀한 정의는 아니며, 일반적으로 다음과 같이 정의한다.

 

$A\cdot x = \lambda \cdot x$이며 $x \neq o$일 때의 $x$는 고유벡터, $\lambda$는 고윳값이다.

 

  첫 번째 식을 이항하여 $A\cdot x - \lambda \cdot x=  (A - \lambda) \cdot x = O$ 와 같이 표현할 수 있는데, 이때 해에 해당하는 벡터 $x$가 자명한 해를 가지기 위해서는 행렬 $(A - \lambda) $가 역행렬로 이항하여 우변의 $O$에 곱해질 수 없어야 한다. 즉, 행렬 A가 주어졌을 때  $det(A - \lambda) = 0$을 만족하는 $\lambda$를 고윳값, 구해진 고윳값을 대입하여 방정식 $A\cdot x = \lambda \cdot x$의 자명해를 구한 것을 고유벡터라고 할 수 있다. 이때, 비가역행렬임을 증명하는 행렬식  $det(A - \lambda) = 0$를 A의 특성방정식(characteristic equation)이라고 한다. 

 

  기하학적으로는 벡터 $x$에 대하여 기존 좌표에서 $A$만큼의 선형변환하는 것을 새로운 축을 정의한 좌표에서 $\lambda$만큼 상수배하는 것으로 표현하는 것이다. 고윳값과 고유벡터의 더 자세한 의의에 대해서는 추가로 학습한 뒤 다시 정리할 예정이다.

 

 

 

 

  행렬이 주어졌을 때 고윳값을 구하는 것은 어렵지 않다. 특정 행렬에 $\lambda \cdot I$를 뺀 행렬인 $A -\lambda \cdot I$의 행렬식, 즉 $\lambda$에 대한 $n$차 방정식의 해가 바로 고윳값인 것이다. 이때, $n$차 방정식이므로 $n$개의 고윳값이 도출되며, 방정식이 중근을 가질 경우 $n$개 이하일 수도 있다.

  고윳값을 구하는 알고리즘은 다음과 같다(Github)  

1
2
3
4
5
6
7
8
9
10
11
12
def eigen_value(matrix):
    
    dim = len(matrix)
    I = np.identity(dim)
    
    l = sym.symbols('l'#람다 변수 객체 정의
    matrix_cal = l*- A #고윳값 계산을 위한 연립방정식
    equation = det_cofactor(matrix_cal) #행렬식으로 변환(가우스 소거법을 사용하는 np.linalg.det는 사용 불가)
    
    eigen_value = sym.solve(equation)
    
    return eigen_value
cs

 

  고윳값 알고리즘에는 이전에 정의한 det_cofactor(여인수 전개) 함수를 사용했다. 람다를 미지수로 놓고 식을 구성하기 위해 sympy 라이브러리의 symbol 메서드를 사용하였는데, 미지수가 들어간 행렬의 경우 이전에 같이 정의했던 가우스 소거법을 이용한 여인수 전개나, 넘파이의 linalg.det 메서드를 사용할 수 없었다. 여인수 전개나 라이프니츠 공식의 경우 문제 없이 사용이 가능했다. 임의의 행렬을 입력하고, 여인수 전개 결과 equation 객체에 다음과 같은 행렬식이 반환되었다.   $n$차 방정식인 행렬식을 풀기 위해 sympy.solve를 사용했다. 

 

 

 

  정의된 eigen_value 함수에 행렬을 입력하였을 때 정상적으로 고윳값이 속한 리스트를 반환하는 것을 확인할 수 있었다. sympy 라이브러리는 결과값으로 일반적인 float이 아니라, 'Float'으로 인식되는 상이한 자료형을 반환(실제로 주피터 노트북에서 객체를 직접 호출하여 출력하면 파이썬의 기본 int/float등 과는 다른 이미지가 출력된다)하기 때문에, 리스트로 반환되는 해, 즉 교윳값들을 바로 연산에 활용하기 위해서는 다시 자료형을 변환해주어야만 한다.

 

 

 

고유벡터 연산 결과

  

  고유벡터의 경우, 앞서 계산한 고윳값을 순차적으로 람다에 대입하여 $A -\lambda \cdot I$를 계산한 뒤, 계산된 행렬을  $A'$라고 정의하여 $A' \cdot  = O$이라는 연립방정식을 푸는 과정이 필요하다. 이전에 정의했던 가우스-조르당 소거법의 경우 연립방정식 $Ax = b$에서 $b =  O$인 경우 계산이 불가능하여, 이를 조금 수정하여 새로운 함수를 만들어야 했다.

  아직 일부 케이스에 대해 오류가 발생하여, 고유벡터 알고리즘은 포스트에 따로 삽입하지는 않고 깃허브에만 구현 과정을 남겨두었다(Github).

  고유벡터 $x$가

$x = \begin{pmatrix}  x_{1} \\ x_{2} \\ x_{3} \end{pmatrix}$

일 때, 기약행사다리꼴을 만들기만 하면 정확한 값을 반환하는 일반 방정식 문제와는 다르게 $ x_{1} = x_{2} = x_{3}$과 같이 가우스 소거법의 결과로 변수들의 관계만 도출된다. 따라서 고유벡터를 구한 결과 다음과 같이 벡터 a와 b가 도출되었을 때

 

$a = \begin{pmatrix} 1 \\ 0 \\ 1 \end{pmatrix}, b = \begin{pmatrix} 1 \\ 0 \\ 1 \end{pmatrix}

 

  일반 방정식의 경우 둘의 값은 다르지만, 고유벡터를 구하는 경우 서로 같은 고유벡터를 의미하는 것이 된다. 이때문에 직접 손으로 계산하는 것은 쉬운 반면에 코드로 구현하기가 까다로웠다.

(고유벡터 구현에 관해 참고할 자료나 조언해주실 내용이 있다면 댓글 부탁드립니다.)

 

 

 

  고유벡터는 np.linalg.eig 메서드를 사용하여 쉽게 구할 수 있다. 이때 고윳값과 고유벡터가 모두 출력되는데, 고윳값이 허수인 케이스에도 올바르게 동작한다.

 

 

 

참고자료

1. 프로그래머를 위한 선형대수(히라오카 카즈유키 저, 이창신 옮김) - 길벗(2017)

2. [Youtube] 쑤튜브 : 10분 선형대수 강의 모음(youtu.be/x-Ewz1ukXEA)

3. 고유벡터 관련

m.blog.naver.com/PostView.nhn?blogId=seolgoons&logNo=221330201375&proxyReferer=http:%2F%2F203.233.19.219%2F 

4. 고유벡터 계산기

matrixcalc.org/ko/vectors.html#eigenvectors%28%7B%7B1,0,0,0%7D,%7B-3,-2,0,0%7D,%7B2,3,-1,0%7D,%7B-2,3,0,3%7D%7D%29

5. sympy 관련 : codepractice.tistory.com/73

Comments