[AI Math] 행렬이 뭐에요

행렬이란?

  • 행(row) 벡터를 원소로 가지는 2차원 배열
  • 행(row)과 열(column)이라는 인덱스(index)를 가진다.
  • 행렬의 특정 행(열)을 고정하면 행(열) 벡터라 부른다.
  • 전치행렬 (transpose matrix): 행과 열의 인덱스가 바뀐 행렬
    • $X^T$

행렬을 이해하는 방법 (1)

  • 벡터가 공간에서 한 점을 의미한다면 행렬은 여러 점들을 나타낸다.
  • 행렬의 행벡터 $x_i$ = i번째 데이터
  • 행렬의 $x_{ij}$ = i번째 데이터의 j번째 변수의 값

행렬의 연산

  • 행렬끼리 같은 모양을 가지면 덧셈, 뺄셈, 성분곱, 스칼라곱이 가능
    • 벡터의 연산과 동일
    • 각 인덱스 위치끼리 더하고, 빼고, 곱하면 된다.
  • 행렬 곱셈 (matrix multiplication)

    \[X \times Y = XY\]
    • X의 i번째 행 벡터(row vector)와 Y의 j번째 열 벡터(column vector) 사이의 내적 = $XY_{ij}$
    • X의 열의 개수와 Y의 행의 개수가 같아야 행렬 곱셈 연산 가능
  • 행렬의 내적
    • numpy의 np.inner은 i번째 행벡터와 j번째 행벡터 사이의 내적으로 계산
    • X 행렬과 Y 행렬의 곱셈을 구한다고 가정했을 때, X 행렬과 Y의 전치행렬을 np.inner했을 때 구할 수 있다.

행렬을 이해하는 방법 (2)

  • 벡터공간에서 사용되는 연산자(operator)
  • 행렬곱을 통해 벡터를 다른 차원의 공간으로 보낼 수 있다.
    • 서로 다른 크기의 벡터를 연결해주는 연산자로 쓰일 수 있다는 뜻
    • ex) n의 길이를 가지는 z벡터, m의 길이를 가지는 x벡터가 있을 때, z벡터는 x벡터와 n * m의 길이를 가지는 임의의 A 행렬을 행렬곱해주며 표현 가능

      \[z = Ax\] \[(n \times 1) = (n \times m) * (m \times 1)\]

역행렬 (inverse matrix)

  • 행렬 $A$의 연산을 거꾸로 돌리는 행렬
    • $A^{-1}$
  • 행과 열의 숫자가 같고, 행렬식(determinant)이 0이 아닌 경우에만 계산 가능
  • 행렬과 그 행렬의 역행렬을 서로 곱해주었을 때는 항등행렬(identity matrix)이 나온다.
  • 역행렬을 계산할 수 없다면 유사역행렬(pseudo-inverse) 또는 무어-펜로즈(Moore-Penrose) 역행렬 $A^+$를이용

    \[n \geq m, A^+ = (A^T A)^{-1}A^T\] \[n \leq m, A^+ = A^T(A A^T)^{-1}\]

역행렬의 응용

  • 연립방정식 풀기
    • $n \leq m$ (식이 변수의 개수보다 작거나 같을 경우)

      \[a_{11}x_1 + \cdots a_{1m}x_m = b_1\] \[\vdots\] \[a_{n1}x_1 + \cdots a_{nm}x_m = b_n\] \[Ax = b\] \[x = A^+b\] \[x = A^T(A A^T)^{-1}b\]
  • 선형회귀분석
    • $n \geq m$ (데이터가 변수의 개수보다 많거나 같을 경우)

      \[X\beta = \hat{y} \approx y\]

      $\lVert y - \hat{y} \rVert_2 $ 의 값을 최소화하는 $\beta$를 찾는 것이 목표

      \[\beta = X^+y\] \[\beta = (X^T X)^{-1}X^Ty\]
    • 연립방정식과는 달리 행이 더 크므로 방정식을 풀 수는 없다.
    • 이대로만 풀게되면 scikit-learn의 LinearRegression과 결과가 다르게 나오는데, 이는 y 절편(intercept) 항을 추가해주지 않았기 때문. scikit-learn은 알아서 추가를 해준다.
    import numpy as np
    
    # Moore-Penrose 역행렬을 이용한 Linear Regression
    X_ = np.array([np.append(x, [1]) for x in X]) # y 절편(intercept) 항 추가 
    beta = np.linalg.pinv(X_) @ y
    y_test = np.append(x, [1]) @ beta
    

Leave a comment